Skip to content

Commit

Permalink
Merge pull request OSGeo#9095 from rouault/isspace
Browse files Browse the repository at this point in the history
Fix calls to isspace(), isdigit(), isalnum(), isalpha(), islower(), isupper() to make sure argument is unsigned, otherwise unspecified behavior
  • Loading branch information
rouault authored Jan 25, 2024
2 parents e95f1fa + c80de4b commit 862b44d
Show file tree
Hide file tree
Showing 89 changed files with 335 additions and 248 deletions.
3 changes: 2 additions & 1 deletion apps/gdallocationinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,8 @@ MAIN_START(argc, argv)
{
papszOpenOptions = CSLAddString(papszOpenOptions, argv[++i]);
}
else if (argv[i][0] == '-' && !isdigit(argv[i][1]))
else if (argv[i][0] == '-' &&
!isdigit(static_cast<unsigned char>(argv[i][1])))
Usage(true);

else if (pszSrcFilename == nullptr)
Expand Down
2 changes: 1 addition & 1 deletion apps/gdalwarp_lib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5448,7 +5448,7 @@ GDALWarpAppOptionsNew(char **papszArgv,
return nullptr;
}
if (i < nArgc - 1 && atoi(papszArgv[i + 1]) >= 0 &&
isdigit(papszArgv[i + 1][0]))
isdigit(static_cast<unsigned char>(papszArgv[i + 1][0])))
{
psOptions->aosTransformerOptions.SetNameValue(
"REFINE_MINIMUM_GCPS", papszArgv[++i]);
Expand Down
3 changes: 2 additions & 1 deletion frmts/aaigrid/aaigriddataset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1134,7 +1134,8 @@ GDALDataset *AAIGDataset::CommonOpen(GDALOpenInfo *poOpenInfo,
poOpenInfo->pabyHeader[i - 1] == '\r' ||
poOpenInfo->pabyHeader[i - 2] == '\r')
{
if ((!isalpha(poOpenInfo->pabyHeader[i]) ||
if ((!isalpha(static_cast<unsigned char>(
poOpenInfo->pabyHeader[i])) ||
// null seems to be specific of D12 software
// See https://github.com/OSGeo/gdal/issues/5095
(i + 5 < poOpenInfo->nHeaderBytes &&
Expand Down
2 changes: 1 addition & 1 deletion frmts/aigrid/aigopen.c
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,7 @@ VSILFILE *AIGLLOpen(const char *pszFilename, const char *pszAccess)
for (i = (int)strlen(pszUCFilename) - 1;
pszUCFilename[i] != '/' && pszUCFilename[i] != '\\'; i--)
{
pszUCFilename[i] = (char)toupper(pszUCFilename[i]);
pszUCFilename[i] = (char)toupper((unsigned char)(pszUCFilename[i]));
}

fp = VSIFOpenL(pszUCFilename, pszAccess);
Expand Down
2 changes: 1 addition & 1 deletion frmts/eeda/eedadataset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ GDALEEDALayer::GDALEEDALayer(GDALEEDADataset *poDS,
CPLString osLaundered(osCollection);
for (size_t i = 0; i < osLaundered.size(); i++)
{
if (!isalnum(static_cast<int>(osLaundered[i])))
if (!isalnum(static_cast<unsigned char>(osLaundered[i])))
{
osLaundered[i] = '_';
}
Expand Down
5 changes: 3 additions & 2 deletions frmts/georaster/oci_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1433,7 +1433,8 @@ void OWUpperIfNoQuotes(char *pszText)

for (size_t i = 0; i < nSize; i++)
{
pszText[i] = static_cast<char>(toupper(pszText[i]));
pszText[i] =
static_cast<char>(toupper(static_cast<unsigned char>(pszText[i])));
}
}

Expand Down Expand Up @@ -1488,7 +1489,7 @@ CPLString OWParseSDO_GEOR_INIT(const char *pszInsert, int nField)

for (pszIn = szUpcase; *pszIn != '\0'; pszIn++)
{
*pszIn = (char)toupper(*pszIn);
*pszIn = (char)toupper(static_cast<unsigned char>(*pszIn));
}

char *pszStart = strstr(szUpcase, "SDO_GEOR.INIT");
Expand Down
6 changes: 3 additions & 3 deletions frmts/grib/degrib/degrib/clock.c
Original file line number Diff line number Diff line change
Expand Up @@ -1954,7 +1954,7 @@ static int Clock_GetWord (char **Start, char **End, char word[30],
f_integer = 1;
while ((*ptr != ' ') && (*ptr != ',') && (*ptr != '\0')) {
if (cnt < 29) {
word[cnt] = (char) toupper (*ptr);
word[cnt] = (char) toupper ((unsigned char)*ptr);
cnt++;
}
if (*ptr == ':') {
Expand All @@ -1972,12 +1972,12 @@ static int Clock_GetWord (char **Start, char **End, char word[30],
f_integer = 0;
}
} else if (*ptr == '.') {
if (!isdigit (*(ptr + 1))) {
if (!isdigit ((unsigned char)*(ptr + 1))) {
break;
} else {
f_integer = 0;
}
} else if (!isdigit (*ptr)) {
} else if (!isdigit ((unsigned char)*ptr)) {
f_integer = 0;
}
ptr++;
Expand Down
4 changes: 2 additions & 2 deletions frmts/grib/degrib/degrib/metaname.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -867,8 +867,8 @@ static void ElemNamePerc (uChar mstrVersion, uShort2 center, uShort2 subcenter,
* the percentile (or exceedance value) so don't tack on percentile here.*/
size_t len = strlen(pszShortName);
if (len >= 2 &&
isdigit(pszShortName[len -1]) &&
isdigit(pszShortName[len -2])) {
isdigit(static_cast<unsigned char>(pszShortName[len -1])) &&
isdigit(static_cast<unsigned char>(pszShortName[len -2]))) {
mallocSprintf (name, "%s", pszShortName);
} else if ((strcmp (pszShortName, "Surge") == 0) ||
(strcmp (pszShortName, "SURGE") == 0)) {
Expand Down
28 changes: 14 additions & 14 deletions frmts/grib/degrib/degrib/myutil.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ int myAtoI (const char *ptr, sInt4 *value)
myAssert (ptr != NULL);
*value = 0;
while (*ptr != '\0') {
if (isdigit (*ptr) || (*ptr == '+') || (*ptr == '-')) {
if (isdigit ((unsigned char)*ptr) || (*ptr == '+') || (*ptr == '-')) {
*value = (int)strtol (ptr, &extra, 10);
myAssert (extra != NULL);
if (*extra == '\0') {
Expand Down Expand Up @@ -283,7 +283,7 @@ int myAtoF (const char *ptr, double *value)
myAssert (ptr != NULL);
*value = 0;
while (*ptr != '\0') {
if (isdigit (*ptr) || (*ptr == '+') || (*ptr == '-') || (*ptr == '.')) {
if (isdigit ((unsigned char)*ptr) || (*ptr == '+') || (*ptr == '-') || (*ptr == '.')) {
*value = strtod (ptr, &extra);
myAssert (extra != NULL);
if (*extra == '\0') {
Expand Down Expand Up @@ -327,15 +327,15 @@ int myIsReal_old (const char *ptr, double *value)
size_t len, i;

*value = 0;
if ((!isdigit (*ptr)) && (*ptr != '.'))
if ((!isdigit ((unsigned char)*ptr)) && (*ptr != '.'))
if (*ptr != '-')
return 0;
len = strlen (ptr);
for (i = 1; i < len - 1; i++) {
if ((!isdigit (ptr[i])) && (ptr[i] != '.'))
if ((!isdigit ((unsigned char)ptr[i])) && (ptr[i] != '.'))
return 0;
}
if ((!isdigit (ptr[len - 1])) && (ptr[len - 1] != '.')) {
if ((!isdigit ((unsigned char)ptr[len - 1])) && (ptr[len - 1] != '.')) {
if (ptr[len - 1] != ',') {
return 0;
} else {
Expand Down Expand Up @@ -702,7 +702,7 @@ void strTrim (char *str)
}

/* Trim the string to the left first. */
for (ptr = str; isspace (*ptr); ptr++) {
for (ptr = str; isspace ((unsigned char)*ptr); ptr++) {
}
/* Did we hit the end of an all space string? */
if (*ptr == '\0') {
Expand All @@ -711,7 +711,7 @@ void strTrim (char *str)
}

/* now work on the right side. */
for (ptr2 = ptr + (strlen (ptr) - 1); isspace (*ptr2); ptr2--) {
for (ptr2 = ptr + (strlen (ptr) - 1); isspace ((unsigned char)*ptr2); ptr2--) {
}

/* adjust the pointer to add the null byte. */
Expand Down Expand Up @@ -873,7 +873,7 @@ void strToUpper (char *str)
return;
}

while ((*ptr++ = toupper (*str++)) != '\0') {
while ((*ptr++ = toupper ((unsigned char)(*str++))) != '\0') {
}
}
#endif
Expand Down Expand Up @@ -908,7 +908,7 @@ void strToLower (char *str)
return;
}

while ((*ptr++ = tolower (*str++)) != '\0') {
while ((*ptr++ = tolower ((unsigned char)*str++)) != '\0') {
}
}
#endif
Expand All @@ -920,7 +920,7 @@ void strToLower (char *str)
int str2lw (char *s) {
int i = 0, len = strlen (s);
while (i < len) {
s[i] = (char) tolower(s[i]);
s[i] = (char) tolower((unsigned char)s[i]);
i++;
}
return len;
Expand Down Expand Up @@ -968,18 +968,18 @@ int strcmpNoCase (const char *str1, const char *str2)
return 1;
}

for (; tolower (*str1) == tolower (*str2); str1++, str2++) {
for (; tolower ((unsigned char)*str1) == tolower ((unsigned char)*str2); str1++, str2++) {
if (*str1 == '\0')
return 0;
}
return (tolower (*str1) - tolower (*str2) < 0) ? -1 : 1;
return (tolower ((unsigned char)*str1) - tolower ((unsigned char)*str2) < 0) ? -1 : 1;
/*
strlen1 = strlen (str1);
strlen2 = strlen (str2);
min = (strlen1 < strlen2) ? strlen1 : strlen2;
for (i = 0; i < min; i++) {
c1 = tolower (str1[i]);
c2 = tolower (str2[i]);
c1 = tolower ((unsigned char)str1[i]);
c2 = tolower ((unsigned char)str2[i]);
if (c1 < c2)
return -1;
if (c1 > c2)
Expand Down
3 changes: 2 additions & 1 deletion frmts/gsg/gsagdataset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,8 @@ CPLErr GSAGRasterBand::IReadBlock(int nBlockXOff, int nBlockYOff, void *pImage)
*szEnd = cOldEnd;

szEnd = szStart;
while (!isdigit(*szEnd) && *szEnd != '.' && *szEnd != '\0')
while (!isdigit(static_cast<unsigned char>(*szEnd)) &&
*szEnd != '.' && *szEnd != '\0')
szEnd++;

continue;
Expand Down
5 changes: 3 additions & 2 deletions frmts/gtiff/geotiff.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1260,8 +1260,9 @@ struct GTiffDriverSubdatasetInfo : public GDALSubdatasetInfo

m_driverPrefixComponent = aosParts[0];

const bool hasDriveLetter{strlen(aosParts[2]) == 1 &&
std::isalpha(aosParts[2][0])};
const bool hasDriveLetter{
strlen(aosParts[2]) == 1 &&
std::isalpha(static_cast<unsigned char>(aosParts[2][0]))};

// Check for drive letter
if (iPartsCount == 4)
Expand Down
6 changes: 4 additions & 2 deletions frmts/hdf4/hdf4drivercore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,11 @@ struct HDF4DriverSubdatasetInfo : public GDALSubdatasetInfo
(strlen(aosParts[3]) > 1 &&
(aosParts[3][0] == '\\' || aosParts[3][0] == '/')) &&
((strlen(aosParts[2]) == 2 &&
std::isalpha(aosParts[2][1])) ||
std::isalpha(
static_cast<unsigned char>(aosParts[2][1]))) ||
(strlen(aosParts[2]) == 1 &&
std::isalpha(aosParts[2][0])))};
std::isalpha(
static_cast<unsigned char>(aosParts[2][0]))))};
m_pathComponent = aosParts[2];

const bool hasProtocol{m_pathComponent.find("/vsicurl/") !=
Expand Down
3 changes: 2 additions & 1 deletion frmts/hdf5/hdf5drivercore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,8 @@ struct HDF5DriverSubdatasetInfo : public GDALSubdatasetInfo

int subdatasetIndex{2};
const bool hasDriveLetter{
part1.length() == 1 && std::isalpha(part1.at(0)) &&
part1.length() == 1 &&
std::isalpha(static_cast<unsigned char>(part1.at(0))) &&
(strlen(aosParts[2]) > 1 &&
(aosParts[2][0] == '\\' ||
(aosParts[2][0] == '/' && aosParts[2][1] != '/')))};
Expand Down
4 changes: 2 additions & 2 deletions frmts/iso8211/ddffielddefn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -641,7 +641,7 @@ char *DDFFieldDefn::ExpandFormat(const char *pszSrc)

// This is a repeated subclause.
else if ((iSrc == 0 || pszSrc[iSrc - 1] == ',') &&
isdigit(pszSrc[iSrc]))
isdigit(static_cast<unsigned char>(pszSrc[iSrc])))
{
const int nRepeat = atoi(pszSrc + iSrc);
// 100: arbitrary number. Higher values might cause performance
Expand All @@ -654,7 +654,7 @@ char *DDFFieldDefn::ExpandFormat(const char *pszSrc)

// Skip over repeat count.
const char *pszNext = pszSrc + iSrc; // Used after for.
for (; isdigit(*pszNext); pszNext++)
for (; isdigit(static_cast<unsigned char>(*pszNext)); pszNext++)
iSrc++;

char *pszContents = ExtractSubstring(pszNext);
Expand Down
5 changes: 3 additions & 2 deletions frmts/mrf/marfa_dataset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1594,8 +1594,9 @@ static inline bool is_absolute(const CPLString &name)
{
return (name.find_first_of("/\\") == 0) // Starts with root
|| (name.size() > 1 && name[1] == ':' &&
isalpha(name[0])) // Starts with drive letter
|| (name[0] == '<'); // Maybe it is XML
isalpha(static_cast<unsigned char>(
name[0]))) // Starts with drive letter
|| (name[0] == '<'); // Maybe it is XML
}

// Add the dirname of path to the beginning of name, if it is relative
Expand Down
6 changes: 3 additions & 3 deletions frmts/netcdf/netcdfdataset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3431,14 +3431,14 @@ void netCDFDataset::SetProjectionFromVar(
for (unsigned int i = 0;
i < strlen(poDS->papszDimName[poDS->nXDimID]) && i < 3; i++)
{
szDimNameX[i] =
(char)tolower((poDS->papszDimName[poDS->nXDimID])[i]);
szDimNameX[i] = (char)tolower(static_cast<unsigned char>(
(poDS->papszDimName[poDS->nXDimID])[i]));
}
szDimNameX[3] = '\0';
// for( unsigned int i = 0;
// (i < strlen(poDS->papszDimName[poDS->nYDimID])
// && i < 3 ); i++ ) {
// szDimNameY[i]=(char)tolower((poDS->papszDimName[poDS->nYDimID])[i]);
// szDimNameY[i]=(char)tolower(static_cast<unsigned char>((poDS->papszDimName[poDS->nYDimID])[i]));
// }
// szDimNameY[3] = '\0';
}
Expand Down
3 changes: 2 additions & 1 deletion frmts/netcdf/netcdfdrivercore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,8 @@ struct NCDFDriverSubdatasetInfo : public GDALSubdatasetInfo
const bool hasDriveLetter{
(strlen(aosParts[2]) > 1 &&
(aosParts[2][0] == '\\' || aosParts[2][0] == '/')) &&
part1.length() == 1 && std::isalpha(part1.at(0))};
part1.length() == 1 &&
std::isalpha(static_cast<unsigned char>(part1.at(0)))};

const bool hasProtocol{part1 == "/vsicurl/http" ||
part1 == "/vsicurl/https" ||
Expand Down
14 changes: 7 additions & 7 deletions frmts/nitf/mgrs.c
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ static long Check_Zone(char *MGRS, long *zone_exists)
while (MGRS[i] == ' ')
i++;
j = i;
while (isdigit(MGRS[i]))
while (isdigit((unsigned char)MGRS[i]))
i++;
num_digits = i - j;
if (num_digits <= 2)
Expand Down Expand Up @@ -428,7 +428,7 @@ static long Break_MGRS_String(char *MGRS, long *Zone,
while (MGRS[i] == ' ')
i++; /* skip any leading blanks */
j = i;
while (isdigit(MGRS[i]))
while (isdigit((unsigned char)MGRS[i]))
i++;
num_digits = i - j;
if (num_digits <= 2)
Expand All @@ -448,26 +448,26 @@ static long Break_MGRS_String(char *MGRS, long *Zone,
error_code |= MGRS_STRING_ERROR;
j = i;

while (isalpha(MGRS[i]))
while (isalpha((unsigned char)MGRS[i]))
i++;
num_letters = i - j;
if (num_letters == 3)
{
/* get letters */
Letters[0] = (toupper(MGRS[j]) - (long)'A');
Letters[0] = (toupper((unsigned char)MGRS[j]) - (long)'A');
if ((Letters[0] == LETTER_I) || (Letters[0] == LETTER_O))
error_code |= MGRS_STRING_ERROR;
Letters[1] = (toupper(MGRS[j + 1]) - (long)'A');
Letters[1] = (toupper((unsigned char)MGRS[j + 1]) - (long)'A');
if ((Letters[1] == LETTER_I) || (Letters[1] == LETTER_O))
error_code |= MGRS_STRING_ERROR;
Letters[2] = (toupper(MGRS[j + 2]) - (long)'A');
Letters[2] = (toupper((unsigned char)MGRS[j + 2]) - (long)'A');
if ((Letters[2] == LETTER_I) || (Letters[2] == LETTER_O))
error_code |= MGRS_STRING_ERROR;
}
else
error_code |= MGRS_STRING_ERROR;
j = i;
while (isdigit(MGRS[i]))
while (isdigit((unsigned char)MGRS[i]))
i++;
num_digits = i - j;
if ((num_digits <= 10) && (num_digits % 2 == 0))
Expand Down
14 changes: 7 additions & 7 deletions frmts/nitf/nitfdataset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6224,9 +6224,9 @@ static bool NITFWriteDES(VSILFILE *&fp, const char *pszFilename,
char szDESITEM[LEN_DESITEM + 1];
memcpy(szDESITEM, pabyDESData + 169 + LEN_DESOFLW, LEN_DESITEM);
szDESITEM[LEN_DESITEM] = '\0';
if (!isdigit(static_cast<int>(szDESITEM[0])) ||
!isdigit(static_cast<int>(szDESITEM[1])) ||
!isdigit(static_cast<int>(szDESITEM[2])))
if (!isdigit(static_cast<unsigned char>(szDESITEM[0])) ||
!isdigit(static_cast<unsigned char>(szDESITEM[1])) ||
!isdigit(static_cast<unsigned char>(szDESITEM[2])))
{
CPLError(CE_Failure, CPLE_AppDefined,
"Invalid value for DESITEM: '%s'", szDESITEM);
Expand Down Expand Up @@ -6328,10 +6328,10 @@ static bool NITFWriteDES(VSILFILE *&fp, const char *pszFilename,
169 + (bIsTRE_OVERFLOW ? LEN_DESOFLW + LEN_DESITEM : 0);
memcpy(szDESSHL, pabyDESData + OFFSET_DESSHL, LEN_DESSHL);
szDESSHL[LEN_DESSHL] = '\0';
if (!isdigit(static_cast<int>(szDESSHL[0])) ||
!isdigit(static_cast<int>(szDESSHL[1])) ||
!isdigit(static_cast<int>(szDESSHL[2])) ||
!isdigit(static_cast<int>(szDESSHL[3])))
if (!isdigit(static_cast<unsigned char>(szDESSHL[0])) ||
!isdigit(static_cast<unsigned char>(szDESSHL[1])) ||
!isdigit(static_cast<unsigned char>(szDESSHL[2])) ||
!isdigit(static_cast<unsigned char>(szDESSHL[3])))
{
CPLError(CE_Failure, CPLE_AppDefined, "Invalid value for DESSHL: '%s'",
szDESSHL);
Expand Down
2 changes: 1 addition & 1 deletion frmts/pcidsk/sdk/channel/ctiledchannel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -717,7 +717,7 @@ void CTiledChannel::JPEGCompressBlock( PCIDSKBuffer &oDecompressedData,

const char * compression = mpoTileLayer->GetCompressType();

if (strlen(compression) > 4 && isdigit(compression[4]))
if (strlen(compression) > 4 && isdigit(static_cast<unsigned char>(compression[4])))
quality = atoi(compression + 4);

/* -------------------------------------------------------------------- */
Expand Down
Loading

0 comments on commit 862b44d

Please sign in to comment.