Wstring view overrun (#884)

This commit is contained in:
Scott Freeman 2020-01-06 16:44:40 -05:00 committed by Matt Cooley
parent fb18b639e3
commit 563404fd99
2 changed files with 10 additions and 3 deletions

View File

@ -215,10 +215,12 @@ int CCalcEngine::IsNumberInvalid(const wstring& numberString, int iMaxExp, int i
\****************************************************************************/ \****************************************************************************/
vector<uint32_t> CCalcEngine::DigitGroupingStringToGroupingVector(wstring_view groupingString) vector<uint32_t> CCalcEngine::DigitGroupingStringToGroupingVector(wstring_view groupingString)
{ {
vector<uint32_t> grouping{}; vector<uint32_t> grouping;
uint32_t currentGroup = 0; uint32_t currentGroup = 0;
wchar_t* next = nullptr; wchar_t* next = nullptr;
for (const wchar_t* itr = groupingString.data(); *itr != L'\0'; ++itr) const wchar_t* begin = groupingString.data();
const wchar_t* end = begin + groupingString.length();
for (auto itr = begin; itr != end; ++itr)
{ {
// Try to parse a grouping number from the string // Try to parse a grouping number from the string
currentGroup = wcstoul(itr, &next, 10); currentGroup = wcstoul(itr, &next, 10);
@ -232,7 +234,7 @@ vector<uint32_t> CCalcEngine::DigitGroupingStringToGroupingVector(wstring_view g
// If we found a grouping and aren't at the end of the string yet, // If we found a grouping and aren't at the end of the string yet,
// jump to the next position in the string (the ';'). // jump to the next position in the string (the ';').
// The loop will then increment us to the next character, which should be a number. // The loop will then increment us to the next character, which should be a number.
if (next && (static_cast<size_t>(next - groupingString.data()) < groupingString.length())) if (next && (static_cast<size_t>(next - begin) < groupingString.length()))
{ {
itr = next; itr = next;
} }

View File

@ -177,6 +177,11 @@ namespace CalculatorEngineTests
groupingVector = { 4, 7, 0 }; groupingVector = { 4, 7, 0 };
VERIFY_ARE_EQUAL(groupingVector, CCalcEngine::DigitGroupingStringToGroupingVector(L"4;16;7;25;0"), L"Verify we ignore oversize grouping"); VERIFY_ARE_EQUAL(groupingVector, CCalcEngine::DigitGroupingStringToGroupingVector(L"4;16;7;25;0"), L"Verify we ignore oversize grouping");
groupingVector = { 3, 0 };
constexpr wstring_view nonRepeatingGrouping = L"3;0;0";
constexpr wstring_view repeatingGrouping = nonRepeatingGrouping.substr(0, 3);
VERIFY_ARE_EQUAL(groupingVector, CCalcEngine::DigitGroupingStringToGroupingVector(repeatingGrouping), L"Verify we don't go past the end of wstring_view range");
} }
TEST_METHOD(TestGroupDigits) TEST_METHOD(TestGroupDigits)