- Changed std::transform(..., ::towlower/::towupper) to _wcsupr/_wcslwr

- MathParser: Fixed stack overflow (and possible crash) when the nested conditional limit is exceeded
This commit is contained in:
Birunthan Mohanathas 2012-01-25 16:00:49 +00:00
parent 430e287bec
commit 35be827071
6 changed files with 22 additions and 30 deletions

View File

@ -117,7 +117,7 @@ private:
static std::wstring StrToLower(const std::wstring& str) { std::wstring strTmp(str); StrToLowerC(strTmp); return strTmp; } static std::wstring StrToLower(const std::wstring& str) { std::wstring strTmp(str); StrToLowerC(strTmp); return strTmp; }
static std::wstring StrToLower(const WCHAR* str) { std::wstring strTmp(str); StrToLowerC(strTmp); return strTmp; } static std::wstring StrToLower(const WCHAR* str) { std::wstring strTmp(str); StrToLowerC(strTmp); return strTmp; }
static std::wstring& StrToLowerC(std::wstring& str) { std::transform(str.begin(), str.end(), str.begin(), ::towlower); return str; } static std::wstring& StrToLowerC(std::wstring& str) { _wcslwr(&str[0]); return str; }
std::wstring m_Filename; std::wstring m_Filename;

View File

@ -136,15 +136,12 @@ LPCWSTR PluginBridge(LPCWSTR _sCommand, LPCWSTR _sData)
NULLCHECK(_sData); NULLCHECK(_sData);
std::wstring sCommand = _sCommand;
std::transform(sCommand.begin(), sCommand.end(), sCommand.begin(), ::towlower);
// Command GetConfig // Command GetConfig
// Data unquoted full path and filename given to the plugin on initialize // Data unquoted full path and filename given to the plugin on initialize
// (note: this is CaSe-SeNsItIvE!) // (note: this is CaSe-SeNsItIvE!)
// Execution none // Execution none
// Result the config name if found or a blank string if not // Result the config name if found or a blank string if not
if (sCommand == L"getconfig") if (_wcsicmp(_sCommand, L"GetConfig") == 0)
{ {
// returns the config name, lookup by INI file // returns the config name, lookup by INI file
@ -164,7 +161,7 @@ LPCWSTR PluginBridge(LPCWSTR _sCommand, LPCWSTR _sData)
// Data [the config name] // Data [the config name]
// Execution none // Execution none
// Result the HWND to the specified config window if found, 'error' otherwise // Result the HWND to the specified config window if found, 'error' otherwise
if (sCommand == L"getwindow") if (_wcsicmp(_sCommand, L"GetWindow") == 0)
{ {
std::vector<std::wstring> subStrings = CRainmeter::ParseString(_sData); std::vector<std::wstring> subStrings = CRainmeter::ParseString(_sData);
@ -189,7 +186,7 @@ LPCWSTR PluginBridge(LPCWSTR _sCommand, LPCWSTR _sData)
// Data [the config name] // Data [the config name]
// Execution none // Execution none
// Result the value of the variable // Result the value of the variable
if (sCommand == L"getvariable") if (_wcsicmp(_sCommand, L"GetVariable") == 0)
{ {
std::vector<std::wstring> subStrings = CRainmeter::ParseString(_sData); std::vector<std::wstring> subStrings = CRainmeter::ParseString(_sData);
@ -201,11 +198,9 @@ LPCWSTR PluginBridge(LPCWSTR _sCommand, LPCWSTR _sData)
if (meterWindow) if (meterWindow)
{ {
const std::wstring& variable = subStrings[1]; const std::wstring& variable = subStrings[1];
std::wstring result_from_parser;
if (meterWindow->GetParser().GetVariable(variable, result_from_parser)) if (meterWindow->GetParser().GetVariable(variable, g_Buffer))
{ {
g_Buffer = result_from_parser;
return g_Buffer.c_str(); return g_Buffer.c_str();
} }
} }
@ -218,7 +213,7 @@ LPCWSTR PluginBridge(LPCWSTR _sCommand, LPCWSTR _sData)
// Data [the config name] [variable data] // Data [the config name] [variable data]
// Execution the indicated variable is updated // Execution the indicated variable is updated
// Result 'success' if the config was found, 'error' otherwise // Result 'success' if the config was found, 'error' otherwise
if (sCommand == L"setvariable") if (_wcsicmp(_sCommand, L"SetVariable") == 0)
{ {
std::vector<std::wstring> subStrings = CRainmeter::ParseString(_sData); std::vector<std::wstring> subStrings = CRainmeter::ParseString(_sData);

View File

@ -70,7 +70,7 @@ std::wstring CGroup::CreateGroup(const std::wstring& str)
strTmp.assign(str, pos, str.find_last_not_of(L" \t\r\n") - pos + 1); strTmp.assign(str, pos, str.find_last_not_of(L" \t\r\n") - pos + 1);
// Convert to lower // Convert to lower
std::transform(strTmp.begin(), strTmp.end(), strTmp.begin(), ::towlower); _wcslwr(&strTmp[0]);
} }
return strTmp; return strTmp;

View File

@ -22,7 +22,6 @@
#include "MeasureCalc.h" #include "MeasureCalc.h"
#include "MathParser.h" #include "MathParser.h"
static const int MAX_STACK_SIZE = 96;
static const double M_E = 2.7182818284590452354; static const double M_E = 2.7182818284590452354;
static const double M_PI = 3.14159265358979323846; static const double M_PI = 3.14159265358979323846;
@ -172,8 +171,8 @@ static int FindSymbol(const WCHAR* str);
struct Parser struct Parser
{ {
Operation opStack[MAX_STACK_SIZE]; Operation opStack[96];
double valStack[MAX_STACK_SIZE]; double valStack[64];
char opTop; char opTop;
char valTop; char valTop;
int obrDist; int obrDist;
@ -210,28 +209,23 @@ WCHAR eInvPrmCnt[] = L"Invalid function parameter count";
WCHAR* MathParser::Check(const WCHAR* formula) WCHAR* MathParser::Check(const WCHAR* formula)
{ {
int BrCnt = 0; int brackets = 0;
// Brackets Matching // Brackets Matching
while (*formula) while (*formula)
{ {
if (*formula == L'(') if (*formula == L'(')
{ {
++BrCnt; ++brackets;
} }
else if (*formula == L')') else if (*formula == L')')
{ {
--BrCnt; --brackets;
} }
++formula; ++formula;
} }
if (BrCnt != 0) return (brackets != 0) ? eBrackets : NULL;
{
return eBrackets;
}
return NULL;
} }
WCHAR* MathParser::CheckParse(const WCHAR* formula, double* result) WCHAR* MathParser::CheckParse(const WCHAR* formula, double* result)
@ -260,6 +254,12 @@ WCHAR* MathParser::Parse(const WCHAR* formula, CMeasureCalc* calc, double* resul
WCHAR* error; WCHAR* error;
for (;;) for (;;)
{ {
if ((parser.opTop == _countof(parser.opStack) - 2) ||
(parser.valTop == _countof(parser.valStack) - 2))
{
return eInternal;
}
MathTokenType token = GetNextToken(lexer); MathTokenType token = GetNextToken(lexer);
--parser.obrDist; --parser.obrDist;
switch (token) switch (token)

View File

@ -32,19 +32,16 @@ std::unordered_map<std::wstring, Gdiplus::Font*> CMeterString::c_Fonts;
void StringToUpper(std::wstring& str) void StringToUpper(std::wstring& str)
{ {
//change each element of the string to upper case _wcsupr(&str[0]);
std::transform(str.begin(), str.end(), str.begin(), ::towupper);
} }
void StringToLower(std::wstring& str) void StringToLower(std::wstring& str)
{ {
//change each element of the string to lower case _wcslwr(&str[0]);
std::transform(str.begin(), str.end(), str.begin(), ::towlower);
} }
void StringToProper(std::wstring& str) void StringToProper(std::wstring& str)
{ {
//change each element of the string to lower case
if (!str.empty()) if (!str.empty())
{ {
str[0] = towupper(str[0]); str[0] = towupper(str[0]);

View File

@ -42,7 +42,7 @@ public:
{ {
key = name; key = name;
} }
std::transform(key.begin(), key.end(), key.begin(), ::towlower); _wcslwr(&key[0]);
size_t len = _snwprintf_s(buffer, _TRUNCATE, L":%llx:%x", time, size); size_t len = _snwprintf_s(buffer, _TRUNCATE, L":%llx:%x", time, size);
key.append(buffer, len); key.append(buffer, len);