Change UnicodesForPredefinedCharSet() to return a span

Do bounds checking when accessing the returned data.

Change-Id: I450c32901bdae985d7b32eb560ed81deeaa167b2
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/112570
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/font/cpdf_fontencoding.cpp b/core/fpdfapi/font/cpdf_fontencoding.cpp
index ff2baed..9ac25aa 100644
--- a/core/fpdfapi/font/cpdf_fontencoding.cpp
+++ b/core/fpdfapi/font/cpdf_fontencoding.cpp
@@ -1665,10 +1665,14 @@
 }
 
 CPDF_FontEncoding::CPDF_FontEncoding(FontEncoding predefined_encoding) {
-  const uint16_t* pSrc = UnicodesForPredefinedCharSet(predefined_encoding);
-  if (pSrc) {
-    for (size_t i = 0; i < std::size(m_Unicodes); i++)
-      m_Unicodes[i] = pSrc[i];
+  pdfium::span<const uint16_t> src =
+      UnicodesForPredefinedCharSet(predefined_encoding);
+  if (src.empty()) {
+    return;
+  }
+
+  for (size_t i = 0; i < std::size(m_Unicodes); i++) {
+    m_Unicodes[i] = src[i];
   }
 }
 
@@ -1686,10 +1690,10 @@
 
   absl::optional<FontEncoding> predefined;
   for (FontEncoding cs : kEncodings) {
-    const uint16_t* pSrc = UnicodesForPredefinedCharSet(cs);
+    pdfium::span<const uint16_t> src = UnicodesForPredefinedCharSet(cs);
     bool match = true;
     for (size_t i = 0; i < std::size(m_Unicodes); i++) {
-      if (m_Unicodes[i] != pSrc[i]) {
+      if (m_Unicodes[i] != src[i]) {
         match = false;
         break;
       }
@@ -1712,12 +1716,13 @@
 
     return pdfium::MakeRetain<CPDF_Name>(pPool, pName);
   }
-  const uint16_t* pStandard =
+  pdfium::span<const uint16_t> standard =
       UnicodesForPredefinedCharSet(FontEncoding::kWinAnsi);
   auto pDiff = pdfium::MakeRetain<CPDF_Array>();
   for (size_t i = 0; i < std::size(m_Unicodes); i++) {
-    if (pStandard[i] == m_Unicodes[i])
+    if (standard[i] == m_Unicodes[i]) {
       continue;
+    }
 
     pDiff->AppendNew<CPDF_Number>(static_cast<int>(i));
     pDiff->AppendNew<CPDF_Name>(AdobeNameFromUnicode(m_Unicodes[i]));
@@ -1754,10 +1759,11 @@
   return kMacRomanEncoding[charcode];
 }
 
-const uint16_t* UnicodesForPredefinedCharSet(FontEncoding encoding) {
+pdfium::span<const uint16_t> UnicodesForPredefinedCharSet(
+    FontEncoding encoding) {
   switch (encoding) {
     case FontEncoding::kBuiltin:
-      return nullptr;
+      return {};
     case FontEncoding::kWinAnsi:
       return kAdobeWinAnsiEncoding;
     case FontEncoding::kMacRoman:
diff --git a/core/fpdfapi/font/cpdf_fontencoding.h b/core/fpdfapi/font/cpdf_fontencoding.h
index 272c8a6..3553400 100644
--- a/core/fpdfapi/font/cpdf_fontencoding.h
+++ b/core/fpdfapi/font/cpdf_fontencoding.h
@@ -11,6 +11,7 @@
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxcrt/string_pool_template.h"
 #include "core/fxcrt/weak_ptr.h"
+#include "third_party/base/containers/span.h"
 
 enum class FontEncoding {
   kBuiltin = 0,
@@ -27,7 +28,8 @@
 uint32_t CharCodeFromUnicodeForFreetypeEncoding(int encoding, wchar_t unicode);
 wchar_t UnicodeFromAppleRomanCharCode(uint8_t charcode);
 
-const uint16_t* UnicodesForPredefinedCharSet(FontEncoding encoding);
+pdfium::span<const uint16_t> UnicodesForPredefinedCharSet(
+    FontEncoding encoding);
 const char* CharNameFromPredefinedCharSet(FontEncoding encoding,
                                           uint8_t charcode);
 
diff --git a/core/fpdfapi/font/cpdf_truetypefont.cpp b/core/fpdfapi/font/cpdf_truetypefont.cpp
index f19ace9..f0ef497 100644
--- a/core/fpdfapi/font/cpdf_truetypefont.cpp
+++ b/core/fpdfapi/font/cpdf_truetypefont.cpp
@@ -145,17 +145,19 @@
       return;
   }
   if (FXFT_Select_Charmap(face, FT_ENCODING_UNICODE) == 0) {
-    const uint16_t* pUnicodes = UnicodesForPredefinedCharSet(base_encoding);
+    pdfium::span<const uint16_t> unicodes =
+        UnicodesForPredefinedCharSet(base_encoding);
     for (uint32_t charcode = 0; charcode < 256; charcode++) {
       if (m_pFontFile) {
         m_Encoding.SetUnicode(charcode, charcode);
       } else {
         const char* name =
             GetAdobeCharName(FontEncoding::kBuiltin, m_CharNames, charcode);
-        if (name)
+        if (name) {
           m_Encoding.SetUnicode(charcode, UnicodeFromAdobeName(name));
-        else if (pUnicodes)
-          m_Encoding.SetUnicode(charcode, pUnicodes[charcode]);
+        } else if (!unicodes.empty()) {
+          m_Encoding.SetUnicode(charcode, unicodes[charcode]);
+        }
       }
       m_GlyphIndex[charcode] =
           FT_Get_Char_Index(face, m_Encoding.UnicodeFromCharCode(charcode));