Convert FXSYS_wcstof() to take a WideStringView argument.

Then remove a number of UNSAFE_BUFFERS in the process.

Bug: 42271176
Change-Id: Ie84a08fa084ee5495f73ac02c94faec89d1d7a95
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/120710
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Thomas Sepez <tsepez@google.com>
diff --git a/core/fxcrt/css/cfx_cssdeclaration.cpp b/core/fxcrt/css/cfx_cssdeclaration.cpp
index a92676c..76a7b61 100644
--- a/core/fxcrt/css/cfx_cssdeclaration.cpp
+++ b/core/fxcrt/css/cfx_cssdeclaration.cpp
@@ -36,8 +36,7 @@
   DCHECK(!view.IsEmpty());
 
   size_t nUsedLen = 0;
-  float value = UNSAFE_TODO(
-      FXSYS_wcstof(view.unterminated_c_str(), view.GetLength(), &nUsedLen));
+  float value = FXSYS_wcstof(view, &nUsedLen);
   if (nUsedLen == 0 || !isfinite(value)) {
     return std::nullopt;
   }
diff --git a/core/fxcrt/fx_extension.cpp b/core/fxcrt/fx_extension.cpp
index 67a5660..a559649 100644
--- a/core/fxcrt/fx_extension.cpp
+++ b/core/fxcrt/fx_extension.cpp
@@ -29,9 +29,9 @@
 
 }  // namespace
 
-float FXSYS_wcstof(const wchar_t* pwsStr, size_t nLength, size_t* pUsedLen) {
-  // SAFETY: required from caller, enforced by UNSAFE_BUFFER_USAGE in header.
-  auto copied = UNSAFE_BUFFERS(WideString::Create(pwsStr, nLength));
+float FXSYS_wcstof(WideStringView pwsStr, size_t* pUsedLen) {
+  // Force NUL-termination via copied buffer.
+  auto copied = WideString(pwsStr);
   wchar_t* endptr = nullptr;
   float result = wcstof(copied.c_str(), &endptr);
   if (result != result) {
diff --git a/core/fxcrt/fx_extension.h b/core/fxcrt/fx_extension.h
index dbd07cc..281d5c1 100644
--- a/core/fxcrt/fx_extension.h
+++ b/core/fxcrt/fx_extension.h
@@ -14,6 +14,7 @@
 
 #include "build/build_config.h"
 #include "core/fxcrt/compiler_specific.h"
+#include "core/fxcrt/widestring.h"
 
 #if defined(USE_SYSTEM_ICUUC)
 #include <unicode/uchar.h>
@@ -25,9 +26,8 @@
 
 #define FX_IsOdd(a) ((a)&1)
 
-UNSAFE_BUFFER_USAGE float FXSYS_wcstof(const wchar_t* pwsStr,
-                                       size_t nLength,
-                                       size_t* pUsedLen);
+float FXSYS_wcstof(WideStringView pwsStr, size_t* pUsedLen);
+
 UNSAFE_BUFFER_USAGE wchar_t* FXSYS_wcsncpy(wchar_t* dstStr,
                                            const wchar_t* srcStr,
                                            size_t count);
diff --git a/core/fxcrt/fx_extension_unittest.cpp b/core/fxcrt/fx_extension_unittest.cpp
index d187885..6e2a7d2 100644
--- a/core/fxcrt/fx_extension_unittest.cpp
+++ b/core/fxcrt/fx_extension_unittest.cpp
@@ -132,98 +132,92 @@
 
 TEST(fxcrt, FXSYS_wcstof) {
   size_t used_len = 0;
-  EXPECT_FLOAT_EQ(-12.0f, UNSAFE_TODO(FXSYS_wcstof(L"-12", 3, &used_len)));
+  EXPECT_FLOAT_EQ(-12.0f, FXSYS_wcstof(L"-12", &used_len));
   EXPECT_EQ(3u, used_len);
 
   used_len = 0;
-  EXPECT_FLOAT_EQ(12.0f, UNSAFE_TODO(FXSYS_wcstof(L"+12", 3, &used_len)));
+  EXPECT_FLOAT_EQ(12.0f, FXSYS_wcstof(L"+12", &used_len));
   EXPECT_EQ(3u, used_len);
 
   used_len = 0;
-  EXPECT_FLOAT_EQ(123.0f, UNSAFE_TODO(FXSYS_wcstof(L" 123", 4, &used_len)));
+  EXPECT_FLOAT_EQ(123.0f, FXSYS_wcstof(L" 123", &used_len));
   EXPECT_EQ(4u, used_len);
 
   used_len = 0;
-  EXPECT_FLOAT_EQ(123.0f, UNSAFE_TODO(FXSYS_wcstof(L" 123 ", 5, &used_len)));
+  EXPECT_FLOAT_EQ(123.0f, FXSYS_wcstof(L" 123 ", &used_len));
   EXPECT_EQ(4u, used_len);
 
   used_len = 0;
-  EXPECT_FLOAT_EQ(1.0f, UNSAFE_TODO(FXSYS_wcstof(L" 1 2 3 ", 7, &used_len)));
+  EXPECT_FLOAT_EQ(1.0f, FXSYS_wcstof(L" 1 2 3 ", &used_len));
   EXPECT_EQ(2u, used_len);
 
   used_len = 0;
-  EXPECT_FLOAT_EQ(1.5362f, UNSAFE_TODO(FXSYS_wcstof(L"1.5362", 6, &used_len)));
+  EXPECT_FLOAT_EQ(1.5362f, FXSYS_wcstof(L"1.5362", &used_len));
   EXPECT_EQ(6u, used_len);
 
   used_len = 0;
-  EXPECT_FLOAT_EQ(1.0f, UNSAFE_TODO(FXSYS_wcstof(L"1 .5362", 7, &used_len)));
+  EXPECT_FLOAT_EQ(1.0f, FXSYS_wcstof(L"1 .5362", &used_len));
   EXPECT_EQ(1u, used_len);
 
   used_len = 0;
-  EXPECT_FLOAT_EQ(1.0f, UNSAFE_TODO(FXSYS_wcstof(L"1. 5362", 7, &used_len)));
+  EXPECT_FLOAT_EQ(1.0f, FXSYS_wcstof(L"1. 5362", &used_len));
   EXPECT_EQ(2u, used_len);
 
   used_len = 0;
-  EXPECT_FLOAT_EQ(1.5f, UNSAFE_TODO(FXSYS_wcstof(L"1.5.3.6.2", 9, &used_len)));
+  EXPECT_FLOAT_EQ(1.5f, FXSYS_wcstof(L"1.5.3.6.2", &used_len));
   EXPECT_EQ(3u, used_len);
 
   used_len = 0;
-  EXPECT_FLOAT_EQ(0.875f, UNSAFE_TODO(FXSYS_wcstof(L"0.875", 5, &used_len)));
+  EXPECT_FLOAT_EQ(0.875f, FXSYS_wcstof(L"0.875", &used_len));
   EXPECT_EQ(5u, used_len);
 
   used_len = 0;
-  EXPECT_FLOAT_EQ(5.56e-2f,
-                  UNSAFE_TODO(FXSYS_wcstof(L"5.56e-2", 7, &used_len)));
+  EXPECT_FLOAT_EQ(5.56e-2f, FXSYS_wcstof(L"5.56e-2", &used_len));
   EXPECT_EQ(7u, used_len);
 
   used_len = 0;
-  EXPECT_FLOAT_EQ(1.234e10f,
-                  UNSAFE_TODO(FXSYS_wcstof(L"1.234E10", 8, &used_len)));
+  EXPECT_FLOAT_EQ(1.234e10f, FXSYS_wcstof(L"1.234E10", &used_len));
   EXPECT_EQ(8u, used_len);
 
   used_len = 0;
-  EXPECT_TRUE(isinf(
-      UNSAFE_TODO(FXSYS_wcstof(L"1.234E100000000000000", 21, &used_len))));
+  EXPECT_TRUE(isinf(FXSYS_wcstof(L"1.234E100000000000000", &used_len)));
   EXPECT_EQ(21u, used_len);
 
   used_len = 0;
-  EXPECT_FLOAT_EQ(0.0f,
-                  UNSAFE_TODO(FXSYS_wcstof(L"1.234E-128", 10, &used_len)));
+  EXPECT_FLOAT_EQ(0.0f, FXSYS_wcstof(L"1.234E-128", &used_len));
   EXPECT_EQ(10u, 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;
-  EXPECT_FLOAT_EQ(
-      123456789.012345678f,
-      UNSAFE_TODO(FXSYS_wcstof(L"123456789.012345678", 19, &used_len)));
+  EXPECT_FLOAT_EQ(123456789.012345678f,
+                  FXSYS_wcstof(L"123456789.012345678", &used_len));
   EXPECT_EQ(19u, used_len);
 
   // TODO(dsinclair): This is spec'd as rounding when > 16 significant digits
   // prior to the exponent.
   // EXPECT_EQ(100000000000000000, FXSYS_wcstof(L"99999999999999999"));
   used_len = 0;
-  EXPECT_FLOAT_EQ(
-      99999999999999999.0f,
-      UNSAFE_TODO(FXSYS_wcstof(L"99999999999999999", 17, &used_len)));
+  EXPECT_FLOAT_EQ(99999999999999999.0f,
+                  FXSYS_wcstof(L"99999999999999999", &used_len));
   EXPECT_EQ(17u, used_len);
 
   // For https://crbug.com/pdfium/1217
-  EXPECT_FLOAT_EQ(0.0f, UNSAFE_TODO(FXSYS_wcstof(L"e76", 3, nullptr)));
+  EXPECT_FLOAT_EQ(0.0f, FXSYS_wcstof(L"e76", nullptr));
 
   // Overflow to infinity.
   used_len = 0;
-  EXPECT_TRUE(isinf(UNSAFE_TODO(FXSYS_wcstof(
+  EXPECT_TRUE(isinf(FXSYS_wcstof(
       L"88888888888888888888888888888888888888888888888888888888888888888888888"
       L"88888888888888888888888888888888888888888888888888888888888",
-      130, &used_len))));
+      &used_len)));
   EXPECT_EQ(130u, used_len);
 
   used_len = 0;
-  EXPECT_TRUE(isinf(UNSAFE_TODO(FXSYS_wcstof(
+  EXPECT_TRUE(isinf(FXSYS_wcstof(
       L"-8888888888888888888888888888888888888888888888888888888888888888888888"
       L"888888888888888888888888888888888888888888888888888888888888",
-      131, &used_len))));
+      &used_len)));
   EXPECT_EQ(131u, used_len);
 }
 
diff --git a/fxjs/xfa/cjx_object.cpp b/fxjs/xfa/cjx_object.cpp
index a6f69bb..6aac6c9 100644
--- a/fxjs/xfa/cjx_object.cpp
+++ b/fxjs/xfa/cjx_object.cpp
@@ -234,8 +234,7 @@
       break;
     case XFA_AttributeType::Integer:
       SetInteger(eAttr,
-                 FXSYS_roundf(UNSAFE_TODO(FXSYS_wcstof(
-                     wsValue.c_str(), wsValue.GetLength(), nullptr))),
+                 FXSYS_roundf(FXSYS_wcstof(wsValue.AsStringView(), nullptr)),
                  bNotify);
       break;
     case XFA_AttributeType::Measure:
diff --git a/xfa/fxfa/formcalc/cxfa_fmlexer.cpp b/xfa/fxfa/formcalc/cxfa_fmlexer.cpp
index 611e51b..cae5456 100644
--- a/xfa/fxfa/formcalc/cxfa_fmlexer.cpp
+++ b/xfa/fxfa/formcalc/cxfa_fmlexer.cpp
@@ -314,8 +314,7 @@
   // This will set end to the character after the end of the number.
   size_t used_length = 0;
   if (m_nCursor < m_spInput.size()) {
-    UNSAFE_TODO(FXSYS_wcstof(&m_spInput[m_nCursor],
-                             m_spInput.size() - m_nCursor, &used_length));
+    FXSYS_wcstof(WideStringView(m_spInput.subspan(m_nCursor)), &used_length);
   }
   size_t end = m_nCursor + used_length;
   if (used_length == 0 ||
diff --git a/xfa/fxfa/parser/cxfa_measurement.cpp b/xfa/fxfa/parser/cxfa_measurement.cpp
index dfa9cc0..8eaca2c 100644
--- a/xfa/fxfa/parser/cxfa_measurement.cpp
+++ b/xfa/fxfa/parser/cxfa_measurement.cpp
@@ -44,11 +44,10 @@
   }
 
   size_t nUsedLen = 0;
-  float fValue = UNSAFE_TODO(FXSYS_wcstof(wsMeasure.unterminated_c_str(),
-                                          wsMeasure.GetLength(), &nUsedLen));
-  if (!isfinite(fValue))
+  float fValue = FXSYS_wcstof(wsMeasure, &nUsedLen);
+  if (!isfinite(fValue)) {
     fValue = 0.0f;
-
+  }
   Set(fValue, GetUnitFromString(wsMeasure.Substr(nUsedLen)));
 }