Permalink
Browse files

Simplify msDBFWriteAttribute to get rid of compiler warnings in lates…

…t GCC.

Latest GCC shows these warnings when compiling release build:
warning: ‘strncpy’ specified bound depends on the length of the source argument [-Wstringop-overflow=]
warning: ‘strncpy’ output may be truncated copying between 0 and 39 bytes from a string of length 39 [-Wstringop-truncation]
warning: ‘strncpy’ output truncated before terminating nul copying as many bytes from a string as its length [-Wstringop-truncation]

In msDBFWriteAttribute we can replace strncpy with memcpy since we already check for the string length and
we don't want the strncpy capability of writing extra \0 characters.

Also replace the 2 snprintf calls (one for the specific format, and one for the value) with a single one.

As snprintf can handle 0 precision numbers just fine, we don't need a separate branch for that either.
NOTE, this does change the rounding for doubles whose field precision is set to 0.
Before 90.9 would be converted to 90, with the new code it would become 91.
  • Loading branch information...
gogglesguy committed Aug 20, 2018
1 parent 738ea6d commit 23893139adbe042eb944b7ee62ae7067f1600c8f
Showing with 7 additions and 21 deletions.
  1. +7 −21 mapxbase.c
@@ -689,9 +689,9 @@ DBFFieldType msDBFGetFieldInfo( DBFHandle psDBF, int iField, char * pszFieldName
static int msDBFWriteAttribute(DBFHandle psDBF, int hEntity, int iField, void * pValue )
{
unsigned int nRecordOffset;
int i, j;
int i, len;
uchar *pabyRec;
char szSField[40], szFormat[12];
char szSField[40];
/* -------------------------------------------------------------------- */
/* Is this a valid record? */
@@ -740,28 +740,14 @@ static int msDBFWriteAttribute(DBFHandle psDBF, int hEntity, int iField, void *
case 'D':
case 'N':
case 'F':
if( psDBF->panFieldDecimals[iField] == 0 ) {
snprintf( szFormat, sizeof(szFormat), "%%%dd", psDBF->panFieldSize[iField] );
snprintf(szSField, sizeof(szSField), szFormat, (int) *((double *) pValue) );
if( (int) strlen(szSField) > psDBF->panFieldSize[iField] )
szSField[psDBF->panFieldSize[iField]] = '\0';
strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]), szSField, strlen(szSField) );
} else {
snprintf( szFormat, sizeof(szFormat), "%%%d.%df", psDBF->panFieldSize[iField], psDBF->panFieldDecimals[iField] );
snprintf(szSField, sizeof(szSField), szFormat, *((double *) pValue) );
if( (int) strlen(szSField) > psDBF->panFieldSize[iField] )
szSField[psDBF->panFieldSize[iField]] = '\0';
strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]), szSField, strlen(szSField) );
}
snprintf(szSField, sizeof(szSField), "%*.*f", psDBF->panFieldSize[iField], psDBF->panFieldDecimals[iField], *(double*) pValue);
len = strlen((char *) szSField);
memcpy(pabyRec+psDBF->panFieldOffset[iField], szSField, MS_MIN(len, psDBF->panFieldSize[iField]));
break;
default:
if( (int) strlen((char *) pValue) > psDBF->panFieldSize[iField] )
j = psDBF->panFieldSize[iField];
else
j = strlen((char *) pValue);
strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]), (char *) pValue, j );
len = strlen((char *) pValue);
memcpy(pabyRec+psDBF->panFieldOffset[iField], pValue, MS_MIN(len, psDBF->panFieldSize[iField]));
break;
}

0 comments on commit 2389313

Please sign in to comment.