Flag remaining unsafe buffer usage in fxcrt.

-- Suppress enforcement in tests.
-- Also add one missing case in span.h

Change-Id: Ib5a52d858a67545618099bd745a0a173b4a2c2ca
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/117811
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
Reviewed-by: Thomas Sepez <tsepez@google.com>
diff --git a/core/fxcrt/cfx_bitstream_unittest.cpp b/core/fxcrt/cfx_bitstream_unittest.cpp
index 9debbd0..4253f1f 100644
--- a/core/fxcrt/cfx_bitstream_unittest.cpp
+++ b/core/fxcrt/cfx_bitstream_unittest.cpp
@@ -6,16 +6,21 @@
 
 #include <limits>
 
+#include "core/fxcrt/compiler_specific.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace {
 
 uint32_t ReferenceGetBits32(const uint8_t* pData, int bitpos, int nbits) {
   int result = 0;
-  for (int i = 0; i < nbits; i++) {
-    if (pData[(bitpos + i) / 8] & (1 << (7 - (bitpos + i) % 8)))
-      result |= 1 << (nbits - i - 1);
-  }
+  // TODO(tsepez): make safe.
+  UNSAFE_BUFFERS({
+    for (int i = 0; i < nbits; i++) {
+      if (pData[(bitpos + i) / 8] & (1 << (7 - (bitpos + i) % 8))) {
+        result |= 1 << (nbits - i - 1);
+      }
+    }
+  });
   return result;
 }
 
diff --git a/core/fxcrt/fx_extension_unittest.cpp b/core/fxcrt/fx_extension_unittest.cpp
index e59070c..8f503c2 100644
--- a/core/fxcrt/fx_extension_unittest.cpp
+++ b/core/fxcrt/fx_extension_unittest.cpp
@@ -10,6 +10,7 @@
 #include <iterator>
 #include <limits>
 
+#include "core/fxcrt/compiler_specific.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 TEST(fxcrt, FXSYS_IsLowerASCII) {
@@ -199,22 +200,25 @@
   const float fNan = std::numeric_limits<float>::quiet_NaN();
   const float ascending[] = {fMin, 1.0f, 2.0f, fMax, fInf, fNan};
 
-  for (size_t i = 0; i < std::size(ascending); ++i) {
-    for (size_t j = 0; j < std::size(ascending); ++j) {
-      if (i == j) {
-        EXPECT_TRUE(FXSYS_SafeEQ(ascending[i], ascending[j]))
-            << " at " << i << " " << j;
-      } else {
-        EXPECT_FALSE(FXSYS_SafeEQ(ascending[i], ascending[j]))
-            << " at " << i << " " << j;
-      }
-      if (i < j) {
-        EXPECT_TRUE(FXSYS_SafeLT(ascending[i], ascending[j]))
-            << " at " << i << " " << j;
-      } else {
-        EXPECT_FALSE(FXSYS_SafeLT(ascending[i], ascending[j]))
-            << " at " << i << " " << j;
+  // TODO(tsepez): make safe.
+  UNSAFE_BUFFERS({
+    for (size_t i = 0; i < std::size(ascending); ++i) {
+      for (size_t j = 0; j < std::size(ascending); ++j) {
+        if (i == j) {
+          EXPECT_TRUE(FXSYS_SafeEQ(ascending[i], ascending[j]))
+              << " at " << i << " " << j;
+        } else {
+          EXPECT_FALSE(FXSYS_SafeEQ(ascending[i], ascending[j]))
+              << " at " << i << " " << j;
+        }
+        if (i < j) {
+          EXPECT_TRUE(FXSYS_SafeLT(ascending[i], ascending[j]))
+              << " at " << i << " " << j;
+        } else {
+          EXPECT_FALSE(FXSYS_SafeLT(ascending[i], ascending[j]))
+              << " at " << i << " " << j;
+        }
       }
     }
-  }
+  });
 }
diff --git a/core/fxcrt/fx_memory_unittest.cpp b/core/fxcrt/fx_memory_unittest.cpp
index 3196a25..2afd651 100644
--- a/core/fxcrt/fx_memory_unittest.cpp
+++ b/core/fxcrt/fx_memory_unittest.cpp
@@ -8,6 +8,7 @@
 #include <memory>
 
 #include "build/build_config.h"
+#include "core/fxcrt/compiler_specific.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 #if defined(PDF_USE_PARTITION_ALLOC)
@@ -103,8 +104,10 @@
 TEST(fxcrt, AllocZeroesMemory) {
   uint8_t* ptr = FX_Alloc(uint8_t, 32);
   ASSERT_TRUE(ptr);
-  for (size_t i = 0; i < 32; ++i)
-    EXPECT_EQ(0, ptr[i]);
+  for (size_t i = 0; i < 32; ++i) {
+    // TODO(tsepez): make safe.
+    EXPECT_EQ(0, UNSAFE_BUFFERS(ptr[i]));
+  }
   FX_Free(ptr);
 }
 
diff --git a/core/fxcrt/fx_system_unittest.cpp b/core/fxcrt/fx_system_unittest.cpp
index 63f1021..681fad8 100644
--- a/core/fxcrt/fx_system_unittest.cpp
+++ b/core/fxcrt/fx_system_unittest.cpp
@@ -8,6 +8,7 @@
 #include <limits>
 
 #include "build/build_config.h"
+#include "core/fxcrt/compiler_specific.h"
 #include "core/fxcrt/fx_string.h"
 #include "core/fxcrt/fx_system.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -24,55 +25,73 @@
 void Check32BitBase16Itoa(int32_t input, const char* expected_output) {
   const size_t kBufLen = 11;  // "-" + 8 digits + NUL + sentinel.
   char buf[kBufLen];
-  buf[kBufLen - 1] = kSentinel;
-  FXSYS_itoa(input, buf, 16);
-  EXPECT_STREQ(expected_output, buf);
-  EXPECT_EQ(kSentinel, buf[kBufLen - 1]);
+  // TODO(tsepez): make safe.
+  UNSAFE_BUFFERS({
+    buf[kBufLen - 1] = kSentinel;
+    FXSYS_itoa(input, buf, 16);
+    EXPECT_STREQ(expected_output, buf);
+    EXPECT_EQ(kSentinel, buf[kBufLen - 1]);
+  });
 }
 
 void Check32BitBase10Itoa(int32_t input, const char* expected_output) {
   const size_t kBufLen = 13;  // "-" + 10 digits + NUL + sentinel.
   char buf[kBufLen];
-  buf[kBufLen - 1] = kSentinel;
-  FXSYS_itoa(input, buf, 10);
-  EXPECT_STREQ(expected_output, buf);
-  EXPECT_EQ(kSentinel, buf[kBufLen - 1]);
+  // TODO(tsepez): make safe.
+  UNSAFE_BUFFERS({
+    buf[kBufLen - 1] = kSentinel;
+    FXSYS_itoa(input, buf, 10);
+    EXPECT_STREQ(expected_output, buf);
+    EXPECT_EQ(kSentinel, buf[kBufLen - 1]);
+  });
 }
 
 void Check32BitBase2Itoa(int32_t input, const char* expected_output) {
   const size_t kBufLen = 35;  // "-" + 32 digits + NUL + sentinel.
   char buf[kBufLen];
-  buf[kBufLen - 1] = kSentinel;
-  FXSYS_itoa(input, buf, 2);
-  EXPECT_STREQ(expected_output, buf);
-  EXPECT_EQ(kSentinel, buf[kBufLen - 1]);
+  // TODO(tsepez): make safe.
+  UNSAFE_BUFFERS({
+    buf[kBufLen - 1] = kSentinel;
+    FXSYS_itoa(input, buf, 2);
+    EXPECT_STREQ(expected_output, buf);
+    EXPECT_EQ(kSentinel, buf[kBufLen - 1]);
+  });
 }
 
 void Check64BitBase16Itoa(int64_t input, const char* expected_output) {
   const size_t kBufLen = 19;  // "-" + 16 digits + NUL + sentinel.
   char buf[kBufLen];
-  buf[kBufLen - 1] = kSentinel;
-  FXSYS_i64toa(input, buf, 16);
-  EXPECT_STREQ(expected_output, buf);
-  EXPECT_EQ(kSentinel, buf[kBufLen - 1]);
+  // TODO(tsepez): make safe.
+  UNSAFE_BUFFERS({
+    buf[kBufLen - 1] = kSentinel;
+    FXSYS_i64toa(input, buf, 16);
+    EXPECT_STREQ(expected_output, buf);
+    EXPECT_EQ(kSentinel, buf[kBufLen - 1]);
+  });
 }
 
 void Check64BitBase10Itoa(int64_t input, const char* expected_output) {
   const size_t kBufLen = 22;  // "-" + 19 digits + NUL + sentinel.
   char buf[kBufLen];
-  buf[kBufLen - 1] = kSentinel;
-  FXSYS_i64toa(input, buf, 10);
-  EXPECT_STREQ(expected_output, buf);
-  EXPECT_EQ(kSentinel, buf[kBufLen - 1]);
+  // TODO(tsepez): make safe.
+  UNSAFE_BUFFERS({
+    buf[kBufLen - 1] = kSentinel;
+    FXSYS_i64toa(input, buf, 10);
+    EXPECT_STREQ(expected_output, buf);
+    EXPECT_EQ(kSentinel, buf[kBufLen - 1]);
+  });
 }
 
 void Check64BitBase2Itoa(int64_t input, const char* expected_output) {
   const size_t kBufLen = 67;  // "-" + 64 digits + NUL + sentinel.
   char buf[kBufLen];
-  buf[kBufLen - 1] = kSentinel;
-  FXSYS_i64toa(input, buf, 2);
-  EXPECT_STREQ(expected_output, buf);
-  EXPECT_EQ(kSentinel, buf[kBufLen - 1]);
+  // TODO(tsepez): make safe.
+  UNSAFE_BUFFERS({
+    buf[kBufLen - 1] = kSentinel;
+    FXSYS_i64toa(input, buf, 2);
+    EXPECT_STREQ(expected_output, buf);
+    EXPECT_EQ(kSentinel, buf[kBufLen - 1]);
+  });
 }
 
 }  // namespace
diff --git a/core/fxcrt/span.h b/core/fxcrt/span.h
index 0a2ce62..1ab476d 100644
--- a/core/fxcrt/span.h
+++ b/core/fxcrt/span.h
@@ -269,7 +269,8 @@
 
   const span last(size_t count) const {
     CHECK(count <= size_);
-    return span(static_cast<T*>(data_) + (size_ - count), count);
+    return UNSAFE_BUFFERS(
+        span(static_cast<T*>(data_) + (size_ - count), count));
   }
 
   const span subspan(size_t pos, size_t count = dynamic_extent) const {
diff --git a/core/fxcrt/widestring_unittest.cpp b/core/fxcrt/widestring_unittest.cpp
index 7803b53..a16bf45 100644
--- a/core/fxcrt/widestring_unittest.cpp
+++ b/core/fxcrt/widestring_unittest.cpp
@@ -9,6 +9,7 @@
 #include <vector>
 
 #include "build/build_config.h"
+#include "core/fxcrt/compiler_specific.h"
 #include "core/fxcrt/containers/contains.h"
 #include "core/fxcrt/fx_string.h"
 #include "core/fxcrt/span.h"
@@ -1007,7 +1008,8 @@
   WideString str2(L"cl");
   {
     pdfium::span<wchar_t> buffer = str2.GetBuffer(12);
-    wcscpy(buffer.data() + 2, L"ams");
+    // TODO(tsepez): make safe.
+    UNSAFE_BUFFERS(wcscpy(buffer.data() + 2, L"ams"));
   }
   str2.ReleaseBuffer(str2.GetStringLength());
   EXPECT_EQ(L"clams", str2);
@@ -1242,12 +1244,15 @@
       {ByteString("\xD8\x3C\xDF\xA8", 4), L"🎨"},
   };
 
-  for (size_t i = 0; i < std::size(utf16be_decode_cases); ++i) {
-    EXPECT_EQ(
-        WideString::FromUTF16BE(utf16be_decode_cases[i].in.unsigned_span()),
-        utf16be_decode_cases[i].out)
-        << " for case number " << i;
-  }
+  // TODO(tsepez): make safe.
+  UNSAFE_BUFFERS({
+    for (size_t i = 0; i < std::size(utf16be_decode_cases); ++i) {
+      EXPECT_EQ(
+          WideString::FromUTF16BE(utf16be_decode_cases[i].in.unsigned_span()),
+          utf16be_decode_cases[i].out)
+          << " for case number " << i;
+    }
+  });
 }
 
 TEST(WideString, FromUTF16LE) {
@@ -1262,12 +1267,15 @@
       {ByteString("\x3C\xD8\xA8\xDF", 4), L"🎨"},
   };
 
-  for (size_t i = 0; i < std::size(utf16le_decode_cases); ++i) {
-    EXPECT_EQ(
-        WideString::FromUTF16LE(utf16le_decode_cases[i].in.unsigned_span()),
-        utf16le_decode_cases[i].out)
-        << " for case number " << i;
-  }
+  // TODO(tsepez): make safe.
+  UNSAFE_BUFFERS({
+    for (size_t i = 0; i < std::size(utf16le_decode_cases); ++i) {
+      EXPECT_EQ(
+          WideString::FromUTF16LE(utf16le_decode_cases[i].in.unsigned_span()),
+          utf16le_decode_cases[i].out)
+          << " for case number " << i;
+    }
+  });
 }
 
 TEST(WideString, ToUTF16LE) {
@@ -1284,11 +1292,14 @@
       {L"🎨", ByteString("\x3C\xD8\xA8\xDF\0\0", 6)},
   };
 
-  for (size_t i = 0; i < std::size(utf16le_encode_cases); ++i) {
-    EXPECT_EQ(utf16le_encode_cases[i].bs,
-              utf16le_encode_cases[i].ws.ToUTF16LE())
-        << " for case number " << i;
-  }
+  // TODO(tsepez): make safe.
+  UNSAFE_BUFFERS({
+    for (size_t i = 0; i < std::size(utf16le_encode_cases); ++i) {
+      EXPECT_EQ(utf16le_encode_cases[i].bs,
+                utf16le_encode_cases[i].ws.ToUTF16LE())
+          << " for case number " << i;
+    }
+  });
 }
 
 TEST(WideString, EncodeEntities) {