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;