ANALYSIS: Add static casts to is* functions

This fixes a potential problem with passing char values that would be sign-extended and yield unexpected results.
See http://msdn.microsoft.com/en-us/library/ms245348.aspx
This commit is contained in:
Littleboy 2011-06-23 05:42:48 -04:00
parent 7a96e0bfb6
commit b694a78f62
28 changed files with 53 additions and 53 deletions

View file

@ -279,7 +279,7 @@ void registerDefaults() {
// resp. between "--some-option" and "--no-some-option".
#define DO_OPTION_BOOL(shortCmd, longCmd) \
if (isLongCmd ? (!strcmp(s+2, longCmd) || !strcmp(s+2, "no-"longCmd)) : (tolower(s[1]) == shortCmd)) { \
bool boolValue = (islower(s[1]) != 0); \
bool boolValue = (islower(static_cast<unsigned char>(s[1])) != 0); \
s += 2; \
if (isLongCmd) { \
boolValue = !strcmp(s, longCmd); \

View file

@ -38,7 +38,7 @@ namespace Common {
*/
bool ConfigFile::isValidName(const Common::String &name) {
const char *p = name.c_str();
while (*p && (isalnum(*p) || *p == '-' || *p == '_' || *p == '.'))
while (*p && (isalnum(static_cast<unsigned char>(*p)) || *p == '-' || *p == '_' || *p == '.'))
p++;
return *p == 0;
}
@ -116,7 +116,7 @@ bool ConfigFile::loadFromStream(SeekableReadStream &stream) {
// is, verify that it only consists of alphanumerics,
// periods, dashes and underscores). Mohawk Living Books games
// can have periods in their section names.
while (*p && (isalnum(*p) || *p == '-' || *p == '_' || *p == '.'))
while (*p && (isalnum(static_cast<unsigned char>(*p)) || *p == '-' || *p == '_' || *p == '.'))
p++;
if (*p == '\0')
@ -139,7 +139,7 @@ bool ConfigFile::loadFromStream(SeekableReadStream &stream) {
// Skip leading whitespaces
const char *t = line.c_str();
while (isspace(*t))
while (isspace(static_cast<unsigned char>(*t)))
t++;
// Skip empty lines / lines with only whitespace

View file

@ -31,7 +31,7 @@ DECLARE_SINGLETON(Common::ConfigManager);
static bool isValidDomainName(const Common::String &domName) {
const char *p = domName.c_str();
while (*p && (isalnum(*p) || *p == '-' || *p == '_'))
while (*p && (isalnum(static_cast<unsigned char>(*p)) || *p == '-' || *p == '_'))
p++;
return *p == 0;
}
@ -187,7 +187,7 @@ void ConfigManager::loadFromStream(SeekableReadStream &stream) {
// Get the domain name, and check whether it's valid (that
// is, verify that it only consists of alphanumerics,
// dashes and underscores).
while (*p && (isalnum(*p) || *p == '-' || *p == '_'))
while (*p && (isalnum(static_cast<unsigned char>(*p)) || *p == '-' || *p == '_'))
p++;
if (*p == '\0')
@ -205,7 +205,7 @@ void ConfigManager::loadFromStream(SeekableReadStream &stream) {
// Skip leading whitespaces
const char *t = line.c_str();
while (isspace(*t))
while (isspace(static_cast<unsigned char>(*t)))
t++;
// Skip empty lines / lines with only whitespace

View file

@ -405,7 +405,7 @@ void String::trim() {
makeUnique();
// Trim trailing whitespace
while (_size >= 1 && isspace(_str[_size - 1]))
while (_size >= 1 && isspace(static_cast<unsigned char>(_str[_size - 1])))
--_size;
_str[_size] = 0;
@ -606,14 +606,14 @@ String operator+(const String &x, char y) {
}
char *ltrim(char *t) {
while (isspace(*t))
while (isspace(static_cast<unsigned char>(*t)))
t++;
return t;
}
char *rtrim(char *t) {
int l = strlen(t) - 1;
while (l >= 0 && isspace(t[l]))
while (l >= 0 && isspace(static_cast<unsigned char>(t[l])))
t[l--] = 0;
return t;
}

View file

@ -263,7 +263,7 @@ bool XMLParser::vparseIntegerKey(const char *key, int count, va_list args) {
int *num_ptr;
while (count--) {
while (isspace(*key))
while (isspace(static_cast<unsigned char>(*key)))
key++;
num_ptr = va_arg(args, int*);
@ -271,7 +271,7 @@ bool XMLParser::vparseIntegerKey(const char *key, int count, va_list args) {
key = parseEnd;
while (isspace(*key))
while (isspace(static_cast<unsigned char>(*key)))
key++;
if (count && *key++ != ',')
@ -463,10 +463,10 @@ bool XMLParser::parse() {
}
bool XMLParser::skipSpaces() {
if (!isspace(_char))
if (!isspace(static_cast<unsigned char>(_char)))
return false;
while (_char && isspace(_char))
while (_char && isspace(static_cast<unsigned char>(_char)))
_char = _stream->readByte();
return true;
@ -516,7 +516,7 @@ bool XMLParser::parseToken() {
_char = _stream->readByte();
}
return isspace(_char) != 0 || _char == '>' || _char == '=' || _char == '/';
return isspace(static_cast<unsigned char>(_char)) != 0 || _char == '>' || _char == '=' || _char == '/';
}
} // End of namespace Common

View file

@ -294,7 +294,7 @@ protected:
* in their name.
*/
virtual inline bool isValidNameChar(char c) {
return isalnum(c) || c == '_';
return isalnum(static_cast<unsigned char>(c)) || c == '_';
}
/**

View file

@ -112,11 +112,11 @@ WagFileParser::~WagFileParser() {
bool WagFileParser::checkAgiVersionProperty(const WagProperty &version) const {
if (version.getCode() == WagProperty::PC_INTVERSION && // Must be AGI interpreter version property
version.getSize() >= 3 && // Need at least three characters for a version number like "X.Y"
isdigit(version.getData()[0]) && // And the first character must be a digit
isdigit(static_cast<unsigned char>(version.getData()[0])) && // And the first character must be a digit
(version.getData()[1] == ',' || version.getData()[1] == '.')) { // And the second a comma or a period
for (int i = 2; i < version.getSize(); i++) // And the rest must all be digits
if (!isdigit(version.getData()[i]))
if (!isdigit(static_cast<unsigned char>(version.getData()[i])))
return false; // Bail out if found a non-digit after the decimal point
return true;

View file

@ -465,8 +465,8 @@ void AGOSEngine_PN::opn_opcode35() {
void AGOSEngine_PN::opn_opcode36() {
for (int i = 0; i < _dataBase[57] + 1; ++i)
_wordcp[i] = 0;
if (isspace(*_inpp))
while ((*_inpp) && (isspace(*_inpp)))
if (isspace(static_cast<unsigned char>(*_inpp)))
while ((*_inpp) && (isspace(static_cast<unsigned char>(*_inpp))))
_inpp++;
if (*_inpp == 0) {
setScriptReturn(false);
@ -480,7 +480,7 @@ void AGOSEngine_PN::opn_opcode36() {
}
int ct = 1;
while ((*_inpp != '.') && (*_inpp != ',') && (!isspace(*_inpp)) && (*_inpp != '\0') &&
while ((*_inpp != '.') && (*_inpp != ',') && (!isspace(static_cast<unsigned char>(*_inpp))) && (*_inpp != '\0') &&
(*_inpp!='"')) {
if (ct < _dataBase[57])
_wordcp[ct++] = *_inpp;
@ -580,7 +580,7 @@ void AGOSEngine_PN::opn_opcode46() {
return;
}
x++;
while ((*x != '.') && (*x != ',') && (*x != '"') && (!isspace(*x)) && (*x != '\0'))
while ((*x != '.') && (*x != ',') && (*x != '"') && (!isspace(static_cast<unsigned char>(*x))) && (*x != '\0'))
pcf(*x++);
setScriptReturn(true);
}

View file

@ -141,7 +141,7 @@ SaveStateList CineMetaEngine::listSaves(const char *target) const {
for (file = filenames.begin(); file != filenames.end(); ++file) {
// Jump over savegame files that don't end with a digit (e.g. "fw.3" is ok, "fw.a" is not).
if (!isdigit(file->lastChar()))
if (!isdigit(static_cast<unsigned char>(file->lastChar())))
continue;
// Obtain the last digit of the filename, since they correspond to the save slot

View file

@ -159,7 +159,7 @@ void DrasculaEngine::enterName() {
key = getScan();
if (key != 0) {
if (key >= 0 && key <= 0xFF && isalpha(key))
if (key >= 0 && key <= 0xFF && isalpha(static_cast<unsigned char>(key)))
select2[v] = tolower(key);
else if ((key >= Common::KEYCODE_0 && key <= Common::KEYCODE_9) || key == Common::KEYCODE_SPACE)
select2[v] = key;

View file

@ -235,7 +235,7 @@ void Parser::charHandler() {
if (_cmdLineIndex >= kMaxLineSize) {
//MessageBeep(MB_ICONASTERISK);
warning("STUB: MessageBeep() - Command line too long");
} else if (isprint(c)) {
} else if (isprint(static_cast<unsigned char>(c))) {
_cmdLine[_cmdLineIndex++] = c;
_cmdLine[_cmdLineIndex] = '\0';
}

View file

@ -119,7 +119,7 @@ char *strlwr(char *buffer) {
char *result = buffer;
while (*buffer != '\0') {
if (isupper(*buffer))
if (isupper(static_cast<unsigned char>(*buffer)))
*buffer = tolower(*buffer);
buffer++;
}

View file

@ -375,7 +375,7 @@ void GUI::updateSaveList(bool excludeQuickSaves) {
s1 = (*i)[i->size()-3];
s2 = (*i)[i->size()-2];
s3 = (*i)[i->size()-1];
if (!isdigit(s1) || !isdigit(s2) || !isdigit(s3))
if (!isdigit(static_cast<unsigned char>(s1)) || !isdigit(static_cast<unsigned char>(s2)) || !isdigit(static_cast<unsigned char>(s3)))
continue;
s1 -= '0';
s2 -= '0';

View file

@ -265,7 +265,7 @@ void Dialog::setupInputArea() {
*/
bool Dialog::matchCommand(const char *s1, const char *s2) {
bool result = scumm_strnicmp(s1, s2, strlen(s2)) == 0;
_commandCase = isupper(*s1);
_commandCase = isupper(static_cast<unsigned char>(*s1));
return result;
}

View file

@ -524,14 +524,14 @@ DECLARE_COMMAND_PARSER(location) {
ctxt.cmd->_startPos.x = -1000;
ctxt.cmd->_startPos2.x = -1000;
if (_tokens[ctxt.nextToken][0] != '\0') {
if (isdigit(_tokens[ctxt.nextToken][0]) || _tokens[ctxt.nextToken][0] == '-') {
if (isdigit(static_cast<unsigned char>(_tokens[ctxt.nextToken][0])) || _tokens[ctxt.nextToken][0] == '-') {
ctxt.cmd->_startPos.x = atoi(_tokens[ctxt.nextToken]);
ctxt.nextToken++;
ctxt.cmd->_startPos.y = atoi(_tokens[ctxt.nextToken]);
ctxt.nextToken++;
}
if (isdigit(_tokens[ctxt.nextToken][0]) || _tokens[ctxt.nextToken][0] == '-') {
if (isdigit(static_cast<unsigned char>(_tokens[ctxt.nextToken][0])) || _tokens[ctxt.nextToken][0] == '-') {
ctxt.cmd->_startPos2.x = atoi(_tokens[ctxt.nextToken]);
ctxt.nextToken++;
ctxt.cmd->_startPos2.y = atoi(_tokens[ctxt.nextToken]);
@ -677,7 +677,7 @@ DECLARE_COMMAND_PARSER(text) {
createCommand(_parser->_lookup);
if (isdigit(_tokens[1][1])) {
if (isdigit(static_cast<unsigned char>(_tokens[1][1]))) {
ctxt.cmd->_zeta0 = atoi(_tokens[1]);
ctxt.nextToken++;
} else {
@ -714,7 +714,7 @@ DECLARE_COMMAND_PARSER(unary) {
DECLARE_ZONE_PARSER(limits) {
debugC(7, kDebugParser, "ZONE_PARSER(limits) ");
if (isalpha(_tokens[1][1])) {
if (isalpha(static_cast<unsigned char>(_tokens[1][1]))) {
ctxt.z->_flags |= kFlagsAnimLinked;
ctxt.z->_linkedName = _tokens[1];
} else {
@ -1003,7 +1003,7 @@ DECLARE_INSTRUCTION_PARSER(text) {
int _si = 1;
if (isdigit(_tokens[1][1])) {
if (isdigit(static_cast<unsigned char>(_tokens[1][1]))) {
ctxt.inst->_y = atoi(_tokens[1]);
_si = 2;
} else {
@ -1066,7 +1066,7 @@ DECLARE_INSTRUCTION_PARSER(endif) {
void ProgramParser_br::parseRValue(ScriptVar &v, const char *str) {
if (isdigit(str[0]) || str[0] == '-') {
if (isdigit(static_cast<unsigned char>(str[0])) || str[0] == '-') {
v.setImmediate(atoi(str));
return;
}

View file

@ -534,7 +534,7 @@ DECLARE_INSTRUCTION_PARSER(endscript) {
void ProgramParser_ns::parseRValue(ScriptVar &v, const char *str) {
if (isdigit(str[0]) || str[0] == '-') {
if (isdigit(static_cast<unsigned char>(str[0])) || str[0] == '-') {
v.setImmediate(atoi(str));
return;
}

View file

@ -658,7 +658,7 @@ void Talk::stringAnimation(const SpeechParameters *parameters, int startFrame, i
} else if (parameters->animation[0] == 'E') {
// Talking head animation
return;
} else if (!isdigit(parameters->animation[0])) {
} else if (!isdigit(static_cast<unsigned char>(parameters->animation[0]))) {
debug(6, "Error in speak string animation: '%s'", parameters->animation);
return;
} else

View file

@ -238,14 +238,14 @@ reg_t kFormat(EngineState *s, int argc, reg_t *argv) {
/* int writelength; -- unused atm */
if (xfer && (isdigit(xfer) || xfer == '-' || xfer == '=')) {
if (xfer && (isdigit(static_cast<unsigned char>(xfer)) || xfer == '-' || xfer == '=')) {
char *destp;
if (xfer == '0')
fillchar = '0';
else if (xfer == '=')
align = ALIGN_CENTER;
else if (isdigit(xfer) || (xfer == '-'))
else if (isdigit(static_cast<unsigned char>(xfer)) || (xfer == '-'))
source--; // Go to start of length argument
str_leng = strtol(source, &destp, 10);

View file

@ -100,7 +100,7 @@ int16 GfxText16::CodeProcessing(const char *&text, GuiResourceId orgFontId, int1
// cX -> sets textColor to _textColors[X-1]
curCode = textCode[0];
curCodeParm = textCode[1];
if (isdigit(curCodeParm)) {
if (isdigit(static_cast<unsigned char>(curCodeParm))) {
curCodeParm -= '0';
} else {
curCodeParm = -1;

View file

@ -1555,7 +1555,7 @@ void ResourceManager::readResourcePatches() {
name = (*x)->getName();
// SCI1 scheme
if (isdigit(name[0])) {
if (isdigit(static_cast<unsigned char>(name[0]))) {
char *end = 0;
resourceNr = strtol(name.c_str(), &end, 10);
bAdd = (*end == '.'); // Ensure the next character is the period
@ -1563,7 +1563,7 @@ void ResourceManager::readResourcePatches() {
// SCI0 scheme
int resname_len = strlen(szResType);
if (scumm_strnicmp(name.c_str(), szResType, resname_len) == 0
&& !isalpha(name[resname_len + 1])) {
&& !isalpha(static_cast<unsigned char>(name[resname_len + 1]))) {
resourceNr = atoi(name.c_str() + resname_len + 1);
bAdd = true;
}

View file

@ -197,7 +197,7 @@ void ResourceManager::readWaveAudioPatches() {
for (Common::ArchiveMemberList::const_iterator x = files.begin(); x != files.end(); ++x) {
Common::String name = (*x)->getName();
if (isdigit(name[0]))
if (isdigit(static_cast<unsigned char>(name[0])))
processWavePatch(ResourceId(kResourceTypeAudio, atoi(name.c_str())), name);
}
}

View file

@ -90,13 +90,13 @@ public:
assert(def_end != NULL);
char *id_end = def_end;
while (id_end >= def_start && !isdigit(*(id_end-1))) {
while (id_end >= def_start && !isdigit(static_cast<unsigned char>(*(id_end-1)))) {
id_end--;
}
assert(id_end > def_start);
char *id_start = id_end;
while (isdigit(*(id_start - 1))) {
while (isdigit(static_cast<unsigned char>(*(id_start - 1)))) {
id_start--;
}

View file

@ -1383,10 +1383,10 @@ void ScummEngine_v7::loadLanguageBundle() {
} else if (*ptr == '#') {
// Number of subtags following a given basetag. We don't need that
// information so we just skip it
} else if (isdigit(*ptr)) {
} else if (isdigit(static_cast<unsigned char>(*ptr))) {
int idx = 0;
// A number (up to three digits)...
while (isdigit(*ptr)) {
while (isdigit(static_cast<unsigned char>(*ptr))) {
idx = idx * 10 + (*ptr - '0');
ptr++;
}
@ -1424,12 +1424,12 @@ void ScummEngine_v7::loadLanguageBundle() {
for (i = 0; i < _languageIndexSize; i++) {
// First 8 chars in the line give the string ID / 'tag'
int j;
for (j = 0; j < 8 && !isspace(*ptr); j++, ptr++)
for (j = 0; j < 8 && !isspace(static_cast<unsigned char>(*ptr)); j++, ptr++)
_languageIndex[i].tag[j] = toupper(*ptr);
_languageIndex[i].tag[j] = 0;
// After that follows a single space which we skip
assert(isspace(*ptr));
assert(isspace(static_cast<unsigned char>(*ptr)));
ptr++;
// Then comes the translated string: we record an offset to that.

View file

@ -206,7 +206,7 @@ SaveStateList SkyMetaEngine::listSaves(const char *target) const {
// Extract the extension
Common::String ext = file->c_str() + file->size() - 3;
ext.toUppercase();
if (isdigit(ext[0]) && isdigit(ext[1]) && isdigit(ext[2])){
if (isdigit(static_cast<unsigned char>(ext[0])) && isdigit(static_cast<unsigned char>(ext[1])) && isdigit(static_cast<unsigned char>(ext[2]))){
int slotNum = atoi(ext.c_str());
Common::InSaveFile *in = saveFileMan->openForLoading(*file);
if (in) {

View file

@ -114,7 +114,7 @@ bool MoviePlayer::load(uint32 id) {
int startFrame = strtoul(ptr, const_cast<char **>(&ptr), 10);
int endFrame = strtoul(ptr, const_cast<char **>(&ptr), 10);
while (*ptr && isspace(*ptr))
while (*ptr && isspace(static_cast<unsigned char>(*ptr)))
ptr++;
if (startFrame > endFrame) {

View file

@ -188,7 +188,7 @@ static void trydecpoint (LexState *ls, SemInfo *seminfo) {
sprintf(buf, "%.1f", 1.0);
ls->decpoint = '.';
for (i = 0; buf[i]; i++) {
if (!isspace(buf[i]) && !isdigit(buf[i])) {
if (!isspace(static_cast<unsigned char>(buf[i])) && !isdigit(static_cast<unsigned char>(buf[i]))) {
ls->decpoint = buf[i];
break;
}

View file

@ -103,7 +103,7 @@ struct MenuData {
void addCharToDescription(int slot, char chr) {
char *description = saveLoadDescriptionsTable[slot];
int descriptionLen = strlen(description);
if (descriptionLen < 32 && isprint(chr)) {
if (descriptionLen < 32 && isprint(static_cast<unsigned char>(chr))) {
description[descriptionLen] = chr;
description[descriptionLen + 1] = 0;
}

View file

@ -948,7 +948,7 @@ int Font::wordWrapText(const Common::String &str, int maxWidth, Common::Array<Co
if (lineWidth > 0) {
wrapper.add(line, lineWidth);
// Trim left side
while (tmpStr.size() && isspace(tmpStr[0])) {
while (tmpStr.size() && isspace(static_cast<unsigned char>(tmpStr[0]))) {
tmpWidth -= getCharWidth(tmpStr[0]);
tmpStr.deleteChar(0);
}