CHECK range before casting float to int in fxnumber
If fxnumber is created from a float, GetSigned() invokes a
static_cast<int32_t>. If the float is out of range for int32, this will
be undefined behavior. This changes it to crash instead.
Change-Id: I5af914ee73a86d46c38a7b4284cc9bacb178ae5b
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/110970
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fxcrt/fx_number.cpp b/core/fxcrt/fx_number.cpp
index a0f38e6..4e58490 100644
--- a/core/fxcrt/fx_number.cpp
+++ b/core/fxcrt/fx_number.cpp
@@ -13,6 +13,7 @@
#include "core/fxcrt/fx_extension.h"
#include "core/fxcrt/fx_safe_types.h"
#include "core/fxcrt/fx_string.h"
+#include "third_party/base/numerics/safe_conversions.h"
FX_Number::FX_Number()
: m_bIsInteger(true), m_bIsSigned(false), m_UnsignedValue(0) {}
@@ -88,7 +89,11 @@
}
int32_t FX_Number::GetSigned() const {
- return m_bIsInteger ? m_SignedValue : static_cast<int32_t>(m_FloatValue);
+ if (m_bIsInteger) {
+ return m_SignedValue;
+ }
+
+ return pdfium::base::checked_cast<int32_t>(m_FloatValue);
}
float FX_Number::GetFloat() const {
diff --git a/core/fxcrt/fx_number_unittest.cpp b/core/fxcrt/fx_number_unittest.cpp
index deb4cf3..ebfdfe7 100644
--- a/core/fxcrt/fx_number_unittest.cpp
+++ b/core/fxcrt/fx_number_unittest.cpp
@@ -45,6 +45,15 @@
EXPECT_FLOAT_EQ(-100.001f, number2.GetFloat());
}
+TEST(fxnumberDeathTest, FromFloatOutOfIntegerRange) {
+ FX_Number number(1e17f);
+ EXPECT_FALSE(number.IsInteger());
+ EXPECT_TRUE(number.IsSigned());
+ ASSERT_DEATH({ number.GetSigned(); },
+ // The CHECK macro doesn't produce useful error messages
+ "");
+}
+
TEST(fxnumber, FromStringUnsigned) {
struct TestCase {
const char* input;