Spin in CFGAS_FormatString::ParseNum. Consolidate increments of format string index at top of loop to ensure progress is always made, rather than trying to do it in every possible branch of the logic beneath it. Bug: pdfium:1260 Change-Id: I2efeefcfd05ebec59350df4fe7ebec3d93f40426 Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/51550 Reviewed-by: Lei Zhang <thestig@chromium.org> Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/xfa/fgas/crt/cfgas_formatstring.cpp b/xfa/fgas/crt/cfgas_formatstring.cpp index 925598c..b96203d 100644 --- a/xfa/fgas/crt/cfgas_formatstring.cpp +++ b/xfa/fgas/crt/cfgas_formatstring.cpp
@@ -1366,9 +1366,8 @@ if (dot_index < len && (dwFormatStyle & FX_NUMSTYLE_DotVorv)) *wsValue += '.'; if (!bReverseParse) { - ccf = dot_index_f + 1; cc = (dot_index == len) ? len : dot_index + 1; - while (cc < len && ccf < lenf) { + for (ccf = dot_index_f + 1; cc < len && ccf < lenf; ++ccf) { switch (strf[ccf]) { case '\'': { WideString wsLiteral = GetLiteralText(strf, &ccf, lenf); @@ -1378,7 +1377,6 @@ return false; } cc += iLiteralLen; - ccf++; break; } case '9': @@ -1387,7 +1385,6 @@ *wsValue += str[cc]; cc++; - ccf++; break; case 'z': case 'Z': @@ -1399,7 +1396,6 @@ } else { cc++; } - ccf++; break; case 'S': case 's': @@ -1413,7 +1409,6 @@ bNeg = true; cc += iMinusLen; } - ccf++; break; case 'E': { if (cc >= len || (str[cc] != 'E' && str[cc] != 'e')) @@ -1437,7 +1432,6 @@ cc++; } iExponent = bExpSign ? -iExponent : iExponent; - ccf++; break; } case '$': { @@ -1448,7 +1442,6 @@ return false; } cc += iSymbolLen; - ccf++; break; } case 'c': @@ -1461,7 +1454,7 @@ bNeg = true; cc += 2; } - ccf += 2; + ccf++; } break; case 'd': @@ -1474,7 +1467,7 @@ bNeg = true; cc += 2; } - ccf += 2; + ccf++; } break; case '.': @@ -1488,11 +1481,10 @@ !wcsncmp(str + cc, wsSymbol.c_str(), iSysmbolLen)) { cc += iSysmbolLen; } - ccf++; bHavePercentSymbol = true; } break; case '8': { - while (ccf < lenf && strf[ccf] == '8') + while (ccf + 1 < lenf && strf[ccf + 1] == '8') ccf++; while (cc < len && FXSYS_IsDecimalDigit(str[cc])) { @@ -1505,7 +1497,6 @@ wcsncmp(str + cc, wsGroupSymbol.c_str(), iGroupLen) == 0) { cc += iGroupLen; } - ccf++; break; } case '(': @@ -1516,14 +1507,12 @@ return false; cc++; - ccf++; break; default: if (strf[ccf] != str[cc]) return false; cc++; - ccf++; } } if (cc != len)
diff --git a/xfa/fgas/crt/cfgas_formatstring_unittest.cpp b/xfa/fgas/crt/cfgas_formatstring_unittest.cpp index a3b7bd4..4cd24a2 100644 --- a/xfa/fgas/crt/cfgas_formatstring_unittest.cpp +++ b/xfa/fgas/crt/cfgas_formatstring_unittest.cpp
@@ -417,6 +417,11 @@ {L"en", L"123.545,4", L"zzz.zzz,z", L"123.5454"}, }; + static const TestCase failures[] = { + // https://crbug.com/pdfium/1260 + {L"en", L"..", L"VC", L"."}, + }; + for (const auto& test : tests) { WideString result; EXPECT_TRUE(fmt(test.locale)->ParseNum(test.input, test.pattern, &result)) @@ -424,6 +429,12 @@ EXPECT_STREQ(test.output, result.c_str()) << " TEST: " << test.input << ", " << test.pattern; } + + for (const auto& test : failures) { + WideString result; + EXPECT_FALSE(fmt(test.locale)->ParseNum(test.input, test.pattern, &result)) + << " TEST: " << test.input << ", " << test.pattern; + } } TEST_F(CFGAS_FormatStringTest, NumFormat) {