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;