From 35be82707167d866d54e58ecf1421f386f688e39 Mon Sep 17 00:00:00 2001 From: Birunthan Mohanathas Date: Wed, 25 Jan 2012 16:00:49 +0000 Subject: [PATCH] - Changed std::transform(..., ::towlower/::towupper) to _wcsupr/_wcslwr - MathParser: Fixed stack overflow (and possible crash) when the nested conditional limit is exceeded --- Library/ConfigParser.h | 2 +- Library/Export.cpp | 15 +++++---------- Library/Group.cpp | 2 +- Library/MathParser.cpp | 24 ++++++++++++------------ Library/MeterString.cpp | 7 ++----- Library/TintedImage.cpp | 2 +- 6 files changed, 22 insertions(+), 30 deletions(-) diff --git a/Library/ConfigParser.h b/Library/ConfigParser.h index 1c003d81..4a048879 100644 --- a/Library/ConfigParser.h +++ b/Library/ConfigParser.h @@ -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 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; diff --git a/Library/Export.cpp b/Library/Export.cpp index 812edd87..1ba48781 100644 --- a/Library/Export.cpp +++ b/Library/Export.cpp @@ -136,15 +136,12 @@ LPCWSTR PluginBridge(LPCWSTR _sCommand, LPCWSTR _sData) NULLCHECK(_sData); - std::wstring sCommand = _sCommand; - std::transform(sCommand.begin(), sCommand.end(), sCommand.begin(), ::towlower); - // Command GetConfig // Data unquoted full path and filename given to the plugin on initialize // (note: this is CaSe-SeNsItIvE!) // Execution none // 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 @@ -164,7 +161,7 @@ LPCWSTR PluginBridge(LPCWSTR _sCommand, LPCWSTR _sData) // Data [the config name] // Execution none // Result the HWND to the specified config window if found, 'error' otherwise - if (sCommand == L"getwindow") + if (_wcsicmp(_sCommand, L"GetWindow") == 0) { std::vector subStrings = CRainmeter::ParseString(_sData); @@ -189,7 +186,7 @@ LPCWSTR PluginBridge(LPCWSTR _sCommand, LPCWSTR _sData) // Data [the config name] // Execution none // Result the value of the variable - if (sCommand == L"getvariable") + if (_wcsicmp(_sCommand, L"GetVariable") == 0) { std::vector subStrings = CRainmeter::ParseString(_sData); @@ -201,11 +198,9 @@ LPCWSTR PluginBridge(LPCWSTR _sCommand, LPCWSTR _sData) if (meterWindow) { 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(); } } @@ -218,7 +213,7 @@ LPCWSTR PluginBridge(LPCWSTR _sCommand, LPCWSTR _sData) // Data [the config name] [variable data] // Execution the indicated variable is updated // Result 'success' if the config was found, 'error' otherwise - if (sCommand == L"setvariable") + if (_wcsicmp(_sCommand, L"SetVariable") == 0) { std::vector subStrings = CRainmeter::ParseString(_sData); diff --git a/Library/Group.cpp b/Library/Group.cpp index f17307ac..0bce7055 100644 --- a/Library/Group.cpp +++ b/Library/Group.cpp @@ -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); // Convert to lower - std::transform(strTmp.begin(), strTmp.end(), strTmp.begin(), ::towlower); + _wcslwr(&strTmp[0]); } return strTmp; diff --git a/Library/MathParser.cpp b/Library/MathParser.cpp index 8d55606d..4fd37d9d 100644 --- a/Library/MathParser.cpp +++ b/Library/MathParser.cpp @@ -22,7 +22,6 @@ #include "MeasureCalc.h" #include "MathParser.h" -static const int MAX_STACK_SIZE = 96; static const double M_E = 2.7182818284590452354; static const double M_PI = 3.14159265358979323846; @@ -172,8 +171,8 @@ static int FindSymbol(const WCHAR* str); struct Parser { - Operation opStack[MAX_STACK_SIZE]; - double valStack[MAX_STACK_SIZE]; + Operation opStack[96]; + double valStack[64]; char opTop; char valTop; int obrDist; @@ -210,28 +209,23 @@ WCHAR eInvPrmCnt[] = L"Invalid function parameter count"; WCHAR* MathParser::Check(const WCHAR* formula) { - int BrCnt = 0; + int brackets = 0; // Brackets Matching while (*formula) { if (*formula == L'(') { - ++BrCnt; + ++brackets; } else if (*formula == L')') { - --BrCnt; + --brackets; } ++formula; } - if (BrCnt != 0) - { - return eBrackets; - } - - return NULL; + return (brackets != 0) ? eBrackets : NULL; } WCHAR* MathParser::CheckParse(const WCHAR* formula, double* result) @@ -260,6 +254,12 @@ WCHAR* MathParser::Parse(const WCHAR* formula, CMeasureCalc* calc, double* resul WCHAR* error; for (;;) { + if ((parser.opTop == _countof(parser.opStack) - 2) || + (parser.valTop == _countof(parser.valStack) - 2)) + { + return eInternal; + } + MathTokenType token = GetNextToken(lexer); --parser.obrDist; switch (token) diff --git a/Library/MeterString.cpp b/Library/MeterString.cpp index e3bd74e2..532bf964 100644 --- a/Library/MeterString.cpp +++ b/Library/MeterString.cpp @@ -32,19 +32,16 @@ std::unordered_map CMeterString::c_Fonts; void StringToUpper(std::wstring& str) { - //change each element of the string to upper case - std::transform(str.begin(), str.end(), str.begin(), ::towupper); + _wcsupr(&str[0]); } void StringToLower(std::wstring& str) { - //change each element of the string to lower case - std::transform(str.begin(), str.end(), str.begin(), ::towlower); + _wcslwr(&str[0]); } void StringToProper(std::wstring& str) { - //change each element of the string to lower case if (!str.empty()) { str[0] = towupper(str[0]); diff --git a/Library/TintedImage.cpp b/Library/TintedImage.cpp index fee06a43..a08392d2 100644 --- a/Library/TintedImage.cpp +++ b/Library/TintedImage.cpp @@ -42,7 +42,7 @@ public: { 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); key.append(buffer, len);