From 6137483528225c1dc102db44fb2c2bce6c256534 Mon Sep 17 00:00:00 2001 From: Dan Sinclair Date: Tue, 15 May 2018 18:59:46 +0000 Subject: Cap size of exponent when converting floats When detecting the exponent on a floating point number, cap the maximum amount we'll multiply by otherwise we can get excessivly large numbers. Bug: chromium:843074 Change-Id: I6a8d1b4c20b66e305d2727f464119b1e74beb699 Reviewed-on: https://pdfium-review.googlesource.com/32570 Reviewed-by: Henrique Nakashima Commit-Queue: dsinclair --- core/fxcrt/fx_extension.cpp | 17 ++++++++++++++--- core/fxcrt/fx_extension_unittest.cpp | 8 ++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/core/fxcrt/fx_extension.cpp b/core/fxcrt/fx_extension.cpp index b1f2a95d62..a27e0279c6 100644 --- a/core/fxcrt/fx_extension.cpp +++ b/core/fxcrt/fx_extension.cpp @@ -6,13 +6,15 @@ #include "core/fxcrt/fx_extension.h" -#include "core/fxcrt/fx_fallthrough.h" - #include #include +#include + +#include "core/fxcrt/fx_fallthrough.h" float FXSYS_wcstof(const wchar_t* pwsStr, int32_t iLength, int32_t* pUsedLen) { ASSERT(pwsStr); + if (iLength < 0) iLength = static_cast(wcslen(pwsStr)); if (iLength == 0) @@ -62,13 +64,22 @@ float FXSYS_wcstof(const wchar_t* pwsStr, int32_t iLength, int32_t* pUsedLen) { ++iUsedLen; } - size_t exp_value = 0; + int32_t exp_value = 0; while (iUsedLen < iLength) { wchar_t wch = pwsStr[iUsedLen]; if (!std::iswdigit(wch)) break; exp_value = exp_value * 10.0f + (wch - L'0'); + // Exponent is outside the valid range, fail. + if ((negative_exponent && + -exp_value < std::numeric_limits::min_exponent10) || + (!negative_exponent && + exp_value > std::numeric_limits::max_exponent10)) { + *pUsedLen = 0; + return 0.0f; + } + ++iUsedLen; } diff --git a/core/fxcrt/fx_extension_unittest.cpp b/core/fxcrt/fx_extension_unittest.cpp index f7e07c7c65..155b7014b7 100644 --- a/core/fxcrt/fx_extension_unittest.cpp +++ b/core/fxcrt/fx_extension_unittest.cpp @@ -134,6 +134,14 @@ TEST(fxcrt, FXSYS_wcstof) { EXPECT_FLOAT_EQ(1.234e10f, FXSYS_wcstof(L"1.234E10", 8, &used_len)); EXPECT_EQ(8, used_len); + used_len = 0; + EXPECT_FLOAT_EQ(0.0f, FXSYS_wcstof(L"1.234E100000000000000", 21, &used_len)); + EXPECT_EQ(0, used_len); + + used_len = 0; + EXPECT_FLOAT_EQ(0.0f, FXSYS_wcstof(L"1.234E-128", 21, &used_len)); + EXPECT_EQ(0, used_len); + // TODO(dsinclair): This should round as per IEEE 64-bit values. // EXPECT_EQ(L"123456789.01234567", FXSYS_wcstof(L"123456789.012345678")); used_len = 0; -- cgit v1.2.3