Do a bounds check before calling functions defined in cctype

pull/3224/head
Evil Eye 3 years ago
parent c01ba41aa6
commit 751e8cf76b

@ -2,8 +2,8 @@
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <components/misc/stringops.hpp>
#include <components/nif/niffile.hpp>
#include <components/files/constrainedfilestream.hpp>
#include <components/vfs/manager.hpp>
@ -18,18 +18,10 @@ namespace bpo = boost::program_options;
namespace bfs = boost::filesystem;
///See if the file has the named extension
bool hasExtension(std::string filename, std::string extensionToFind)
bool hasExtension(std::string filename, std::string extensionToFind)
{
std::string extension = filename.substr(filename.find_last_of('.')+1);
//Convert strings to lower case for comparison
std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
std::transform(extensionToFind.begin(), extensionToFind.end(), extensionToFind.begin(), ::tolower);
if(extension == extensionToFind)
return true;
else
return false;
return Misc::StringUtils::ciEqual(extension, extensionToFind);
}
///See if the file has the "nif" extension.

@ -17,6 +17,19 @@
#include "textnode.hpp"
#include "valuenode.hpp"
namespace
{
bool isAlpha(char c)
{
return c >= 0 && c <= 255 && std::isalpha(c);
}
bool isDigit(char c)
{
return c >= 0 && c <= 255 && std::isdigit(c);
}
}
namespace CSMFilter
{
struct Token
@ -103,7 +116,7 @@ CSMFilter::Token CSMFilter::Parser::getStringToken()
{
char c = mInput[mIndex];
if (std::isalpha (c) || c==':' || c=='_' || (!string.empty() && std::isdigit (c)) || c=='"' ||
if (isAlpha(c) || c==':' || c=='_' || (!string.empty() && isDigit(c)) || c=='"' ||
(!string.empty() && string[0]=='"'))
string += c;
else
@ -150,7 +163,7 @@ CSMFilter::Token CSMFilter::Parser::getNumberToken()
{
char c = mInput[mIndex];
if (std::isdigit (c))
if (isDigit(c))
{
string += c;
hasDigit = true;
@ -225,10 +238,10 @@ CSMFilter::Token CSMFilter::Parser::getNextToken()
case '!': ++mIndex; return Token (Token::Type_OneShot);
}
if (c=='"' || c=='_' || std::isalpha (c) || c==':')
if (c=='"' || c=='_' || isAlpha(c) || c==':')
return getStringToken();
if (c=='-' || c=='.' || std::isdigit (c))
if (c=='-' || c=='.' || isDigit(c))
return getNumberToken();
error();

@ -8,6 +8,7 @@
#include <stdexcept>
#include <components/esm/cellid.hpp>
#include <components/misc/stringops.hpp>
#include "collectionbase.hpp"
#include "columnbase.hpp"
@ -354,8 +355,7 @@ CSMWorld::LandTextureIdTable::ImportResults CSMWorld::LandTextureIdTable::import
for (int i = 0; i < idCollection()->getSize(); ++i)
{
auto& record = static_cast<const Record<LandTexture>&>(idCollection()->getRecord(i));
std::string texture = record.get().mTexture;
std::transform(texture.begin(), texture.end(), texture.begin(), tolower);
std::string texture = Misc::StringUtils::lowerCase(record.get().mTexture);
if (record.isModified())
reverseLookupMap.emplace(texture, idCollection()->getId(i));
}
@ -376,8 +376,7 @@ CSMWorld::LandTextureIdTable::ImportResults CSMWorld::LandTextureIdTable::import
// Look for a pre-existing record
auto& record = static_cast<const Record<LandTexture>&>(idCollection()->getRecord(oldRow));
std::string texture = record.get().mTexture;
std::transform(texture.begin(), texture.end(), texture.begin(), tolower);
std::string texture = Misc::StringUtils::lowerCase(record.get().mTexture);
auto searchIt = reverseLookupMap.find(texture);
if (searchIt != reverseLookupMap.end())
{

@ -42,7 +42,7 @@ namespace MWInput
bool consumed = SDL_IsTextInputActive() && // Little trick to check if key is printable
(!(SDLK_SCANCODE_MASK & arg.keysym.sym) &&
(std::isprint(arg.keysym.sym) ||
(arg.keysym.sym >= 0 && arg.keysym.sym <= 255 && std::isprint(arg.keysym.sym) ||
// Don't trust isprint for symbols outside the extended ASCII range
(kc == MyGUI::KeyCode::None && arg.keysym.sym > 0xff)));
if (kc != MyGUI::KeyCode::None && !mBindingsManager->isDetectingBindingState())

@ -84,7 +84,7 @@ namespace Files
{
mNext.push(character);
}
if (!mSeenNonWhitespace && !isspace(character))
if (!mSeenNonWhitespace && !(character >= 0 && character <= 255 && isspace(character)))
mSeenNonWhitespace = true;
}
int retval = mNext.front();

@ -172,8 +172,7 @@ namespace Interpreter{
for(unsigned int j = 0; j < globals.size(); j++){
if(globals[j].length() > temp.length()){ // Just in case there's a global with a huuuge name
temp = text.substr(i+1, globals[j].length());
transform(temp.begin(), temp.end(), temp.begin(), ::tolower);
temp = Misc::StringUtils::lowerCase(text.substr(i+1, globals[j].length()));
}
found = check(temp, globals[j], &i, &start);

@ -30,6 +30,11 @@ namespace LuaUtil
{"POTION", ESM::LuaScriptCfg::sPotion},
{"WEAPON", ESM::LuaScriptCfg::sWeapon},
};
bool isSpace(int c)
{
return c >= 0 && c <= 255 && std::isspace(c);
}
}
const std::vector<int> ScriptsConfiguration::sEmpty;
@ -101,11 +106,11 @@ namespace LuaUtil
if (!line.empty() && line.back() == '\r')
line = line.substr(0, line.size() - 1);
while (!line.empty() && std::isspace(line[0]))
while (!line.empty() && isSpace(line[0]))
line = line.substr(1);
if (line.empty() || line[0] == '#') // Skip empty lines and comments
continue;
while (!line.empty() && std::isspace(line.back()))
while (!line.empty() && isSpace(line.back()))
line = line.substr(0, line.size() - 1);
if (!Misc::StringUtils::ciEndsWith(line, ".lua"))
@ -118,7 +123,7 @@ namespace LuaUtil
throw std::runtime_error(Misc::StringUtils::format("No flags found in: %s", std::string(line)));
std::string_view flagsStr = line.substr(0, semicolonPos);
std::string_view scriptPath = line.substr(semicolonPos + 1);
while (std::isspace(scriptPath[0]))
while (isSpace(scriptPath[0]))
scriptPath = scriptPath.substr(1);
// Parse flags
@ -126,10 +131,10 @@ namespace LuaUtil
size_t flagsPos = 0;
while (true)
{
while (flagsPos < flagsStr.size() && (std::isspace(flagsStr[flagsPos]) || flagsStr[flagsPos] == ','))
while (flagsPos < flagsStr.size() && (isSpace(flagsStr[flagsPos]) || flagsStr[flagsPos] == ','))
flagsPos++;
size_t startPos = flagsPos;
while (flagsPos < flagsStr.size() && !std::isspace(flagsStr[flagsPos]) && flagsStr[flagsPos] != ',')
while (flagsPos < flagsStr.size() && !isSpace(flagsStr[flagsPos]) && flagsStr[flagsPos] != ',')
flagsPos++;
if (startPos == flagsPos)
break;

@ -184,17 +184,16 @@ public:
static inline void trim(std::string &s)
{
// left trim
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int ch)
const auto notSpace = [](int ch)
{
return !std::isspace(ch);
}));
// TODO Do we care about multibyte whitespace?
return ch < 0 || ch > 255 || !std::isspace(ch);
};
// left trim
s.erase(s.begin(), std::find_if(s.begin(), s.end(), notSpace));
// right trim
s.erase(std::find_if(s.rbegin(), s.rend(), [](int ch)
{
return !std::isspace(ch);
}).base(), s.end());
s.erase(std::find_if(s.rbegin(), s.rend(), notSpace).base(), s.end());
}
template <class Container>

@ -311,7 +311,7 @@ void Settings::SettingsFileParser::saveSettingsFile(const std::string& file, con
bool Settings::SettingsFileParser::skipWhiteSpace(size_t& i, std::string& str)
{
while (i < str.size() && std::isspace(str[i], std::locale::classic()))
while (i < str.size() && str[i] >= 0 && str[i] <= 255 && std::isspace(str[i], std::locale::classic()))
{
++i;
}

Loading…
Cancel
Save