summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/fxcrt/fx_extension.cpp17
-rw-r--r--core/fxcrt/fx_extension_unittest.cpp8
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 <algorithm>
#include <cwctype>
+#include <limits>
+
+#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<int32_t>(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<float>::min_exponent10) ||
+ (!negative_exponent &&
+ exp_value > std::numeric_limits<float>::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;