Skip to content

Commit

Permalink
Simplify msDBFWriteAttribute to get rid of compiler warnings in lates…
Browse files Browse the repository at this point in the history
…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 2389313
Showing 1 changed file with 7 additions and 21 deletions.
28 changes: 7 additions & 21 deletions mapxbase.c
Expand Up @@ -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? */
Expand Down Expand Up @@ -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;
}

Expand Down

0 comments on commit 2389313

Please sign in to comment.