Remove file-wide unsafe_buffers pragmas from fpdfsdk/fpdf*.cpp

Bug: pdfium:2154
Change-Id: I1fa8eff1f51eda4fb1a10ca0e04095619608c023
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/118970
Reviewed-by: Thomas Sepez <tsepez@google.com>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/fpdfsdk/fpdf_annot.cpp b/fpdfsdk/fpdf_annot.cpp
index 34346b3..c5ff6df 100644
--- a/fpdfsdk/fpdf_annot.cpp
+++ b/fpdfsdk/fpdf_annot.cpp
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#if defined(UNSAFE_BUFFERS_BUILD)
-// TODO(crbug.com/pdfium/2153): resolve buffer safety issues.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "public/fpdf_annot.h"
 
 #include <memory>
@@ -524,8 +519,9 @@
 
   auto ink_coord_list = inklist->AppendNew<CPDF_Array>();
   for (size_t i = 0; i < point_count; i++) {
-    ink_coord_list->AppendNew<CPDF_Number>(points[i].x);
-    ink_coord_list->AppendNew<CPDF_Number>(points[i].y);
+    // TODO(crbug.com/pdfium/2155): investigate safety issues.
+    ink_coord_list->AppendNew<CPDF_Number>(UNSAFE_BUFFERS(points[i].x));
+    ink_coord_list->AppendNew<CPDF_Number>(UNSAFE_BUFFERS(points[i].y));
   }
   return static_cast<int>(inklist->size() - 1);
 }
@@ -882,8 +878,9 @@
       fxcrt::CollectionSize<unsigned long>(*vertices) / 2;
   if (buffer && length >= points_len) {
     for (unsigned long i = 0; i < points_len; ++i) {
-      buffer[i].x = vertices->GetFloatAt(i * 2);
-      buffer[i].y = vertices->GetFloatAt(i * 2 + 1);
+      // TODO(crbug.com/pdfium/2155): investigate safety issues.
+      UNSAFE_BUFFERS(buffer[i].x) = vertices->GetFloatAt(i * 2);
+      UNSAFE_BUFFERS(buffer[i].y) = vertices->GetFloatAt(i * 2 + 1);
     }
   }
   return points_len;
@@ -913,8 +910,9 @@
       fxcrt::CollectionSize<unsigned long>(*path) / 2;
   if (buffer && length >= points_len) {
     for (unsigned long i = 0; i < points_len; ++i) {
-      buffer[i].x = path->GetFloatAt(i * 2);
-      buffer[i].y = path->GetFloatAt(i * 2 + 1);
+      // TODO(crbug.com/pdfium/2155): investigate safety issues.
+      UNSAFE_BUFFERS(buffer[i].x) = path->GetFloatAt(i * 2);
+      UNSAFE_BUFFERS(buffer[i].y) = path->GetFloatAt(i * 2 + 1);
     }
   }
   return points_len;
@@ -1025,11 +1023,12 @@
                          FPDF_WCHAR* buffer,
                          unsigned long buflen) {
   const CPDF_Dictionary* pAnnotDict = GetAnnotDictFromFPDFAnnotation(annot);
-  if (!pAnnotDict)
+  if (!pAnnotDict) {
     return 0;
-
-  return Utf16EncodeMaybeCopyAndReturnLength(pAnnotDict->GetUnicodeTextFor(key),
-                                             buffer, buflen);
+  }
+  // SAFETY: required from caller.
+  return UNSAFE_BUFFERS(Utf16EncodeMaybeCopyAndReturnLength(
+      pAnnotDict->GetUnicodeTextFor(key), buffer, buflen));
 }
 
 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
@@ -1067,7 +1066,9 @@
   static_assert(std::size(kModeKeyForMode) == FPDF_ANNOT_APPEARANCEMODE_COUNT,
                 "length of kModeKeyForMode should be equal to "
                 "FPDF_ANNOT_APPEARANCEMODE_COUNT");
-  const char* mode_key = kModeKeyForMode[appearanceMode];
+
+  // TODO(crbug.com/pdfium/2155): investigate safety issues.
+  const char* mode_key = UNSAFE_BUFFERS(kModeKeyForMode[appearanceMode]);
 
   RetainPtr<CPDF_Dictionary> pApDict =
       pAnnotDict->GetMutableDictFor(pdfium::annotation::kAP);
@@ -1145,8 +1146,9 @@
       static_cast<CPDF_Annot::AppearanceMode>(appearanceMode);
 
   RetainPtr<CPDF_Stream> pStream = GetAnnotAPNoFallback(pAnnotDict.Get(), mode);
-  return Utf16EncodeMaybeCopyAndReturnLength(
-      pStream ? pStream->GetUnicodeText() : WideString(), buffer, buflen);
+  // SAFETY: required from caller.
+  return UNSAFE_BUFFERS(Utf16EncodeMaybeCopyAndReturnLength(
+      pStream ? pStream->GetUnicodeText() : WideString(), buffer, buflen));
 }
 
 FPDF_EXPORT FPDF_ANNOTATION FPDF_CALLCONV
@@ -1220,10 +1222,12 @@
                            FPDF_WCHAR* buffer,
                            unsigned long buflen) {
   const CPDF_FormField* pFormField = GetFormField(hHandle, annot);
-  if (!pFormField)
+  if (!pFormField) {
     return 0;
-  return Utf16EncodeMaybeCopyAndReturnLength(pFormField->GetFullName(), buffer,
-                                             buflen);
+  }
+  // SAFETY: required from caller.
+  return UNSAFE_BUFFERS(Utf16EncodeMaybeCopyAndReturnLength(
+      pFormField->GetFullName(), buffer, buflen));
 }
 
 FPDF_EXPORT int FPDF_CALLCONV
@@ -1250,8 +1254,9 @@
   auto type = static_cast<CPDF_AAction::AActionType>(event);
   CPDF_AAction additional_action = pFormField->GetAdditionalAction();
   CPDF_Action action = additional_action.GetAction(type);
-  return Utf16EncodeMaybeCopyAndReturnLength(action.GetJavaScript(), buffer,
-                                             buflen);
+  // SAFETY: required from caller.
+  return UNSAFE_BUFFERS(Utf16EncodeMaybeCopyAndReturnLength(
+      action.GetJavaScript(), buffer, buflen));
 }
 
 FPDF_EXPORT unsigned long FPDF_CALLCONV
@@ -1260,11 +1265,12 @@
                                     FPDF_WCHAR* buffer,
                                     unsigned long buflen) {
   const CPDF_FormField* pFormField = GetFormField(hHandle, annot);
-  if (!pFormField)
+  if (!pFormField) {
     return 0;
-
-  return Utf16EncodeMaybeCopyAndReturnLength(pFormField->GetAlternateName(),
-                                             buffer, buflen);
+  }
+  // SAFETY: required from caller.
+  return UNSAFE_BUFFERS(Utf16EncodeMaybeCopyAndReturnLength(
+      pFormField->GetAlternateName(), buffer, buflen));
 }
 
 FPDF_EXPORT unsigned long FPDF_CALLCONV
@@ -1273,10 +1279,12 @@
                             FPDF_WCHAR* buffer,
                             unsigned long buflen) {
   const CPDF_FormField* pFormField = GetFormField(hHandle, annot);
-  if (!pFormField)
+  if (!pFormField) {
     return 0;
-  return Utf16EncodeMaybeCopyAndReturnLength(pFormField->GetValue(), buffer,
-                                             buflen);
+  }
+  // SAFETY: required from caller.
+  return UNSAFE_BUFFERS(Utf16EncodeMaybeCopyAndReturnLength(
+      pFormField->GetValue(), buffer, buflen));
 }
 
 FPDF_EXPORT int FPDF_CALLCONV FPDFAnnot_GetOptionCount(FPDF_FORMHANDLE hHandle,
@@ -1299,7 +1307,9 @@
     return 0;
 
   WideString ws = pFormField->GetOptionLabel(index);
-  return Utf16EncodeMaybeCopyAndReturnLength(ws, buffer, buflen);
+  // SAFETY: required from caller.
+  return UNSAFE_BUFFERS(
+      Utf16EncodeMaybeCopyAndReturnLength(ws, buffer, buflen));
 }
 
 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
@@ -1374,8 +1384,9 @@
   std::vector<CPDF_Annot::Subtype> focusable_annot_types;
   focusable_annot_types.reserve(count);
   for (size_t i = 0; i < count; ++i) {
+    // TODO(crbug.com/pdfium/2155): investigate safety issues.
     focusable_annot_types.push_back(
-        static_cast<CPDF_Annot::Subtype>(subtypes[i]));
+        static_cast<CPDF_Annot::Subtype>(UNSAFE_BUFFERS(subtypes[i])));
   }
 
   pFormFillEnv->SetFocusableAnnotSubtypes(focusable_annot_types);
@@ -1413,8 +1424,9 @@
     return false;
 
   for (size_t i = 0; i < focusable_annot_types.size(); ++i) {
-    subtypes[i] =
-        static_cast<FPDF_ANNOTATION_SUBTYPE>(focusable_annot_types[i]);
+    // TODO(crbug.com/pdfium/2155): investigate safety issues.
+    UNSAFE_BUFFERS(subtypes[i] = static_cast<FPDF_ANNOTATION_SUBTYPE>(
+                       focusable_annot_types[i]));
   }
 
   return true;
@@ -1458,11 +1470,12 @@
                                   unsigned long buflen) {
   const CPDFSDK_Widget* pWidget =
       GetRadioButtonOrCheckBoxWidget(hHandle, annot);
-  if (!pWidget)
+  if (!pWidget) {
     return 0;
-
-  return Utf16EncodeMaybeCopyAndReturnLength(pWidget->GetExportValue(), buffer,
-                                             buflen);
+  }
+  // SAFETY: required from caller.
+  return UNSAFE_BUFFERS(Utf16EncodeMaybeCopyAndReturnLength(
+      pWidget->GetExportValue(), buffer, buflen));
 }
 
 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_SetURI(FPDF_ANNOTATION annot,
diff --git a/fpdfsdk/fpdf_attachment.cpp b/fpdfsdk/fpdf_attachment.cpp
index 398bd47..dfd48a7 100644
--- a/fpdfsdk/fpdf_attachment.cpp
+++ b/fpdfsdk/fpdf_attachment.cpp
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#if defined(UNSAFE_BUFFERS_BUILD)
-// TODO(crbug.com/pdfium/2153): resolve buffer safety issues.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "public/fpdf_attachment.h"
 
 #include <limits.h>
@@ -56,7 +51,9 @@
 
   char buf[32];
   for (int i = 0; i < 16; ++i) {
-    FXSYS_IntToTwoHexChars(digest[i], &buf[i * 2]);
+    // TODO(crbug.com/pdfium/2155): resolve safety issues.
+    FXSYS_IntToTwoHexChars(UNSAFE_BUFFERS(digest[i]),
+                           UNSAFE_BUFFERS(&buf[i * 2]));
   }
   return ByteString(buf, 32);
 }
@@ -141,8 +138,9 @@
     return 0;
 
   CPDF_FileSpec spec(pdfium::WrapRetain(pFile));
-  return Utf16EncodeMaybeCopyAndReturnLength(spec.GetFileName(), buffer,
-                                             buflen);
+  // SAFETY: required from caller.
+  return UNSAFE_BUFFERS(
+      Utf16EncodeMaybeCopyAndReturnLength(spec.GetFileName(), buffer, buflen));
 }
 
 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
@@ -216,8 +214,9 @@
                   ->GetUnicodeText();
     }
   }
-
-  return Utf16EncodeMaybeCopyAndReturnLength(value, buffer, buflen);
+  // SAFETY: required from caller.
+  return UNSAFE_BUFFERS(
+      Utf16EncodeMaybeCopyAndReturnLength(value, buffer, buflen));
 }
 
 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
@@ -260,9 +259,13 @@
 
   // Create the file stream and have the filespec dictionary link to it.
   const uint8_t* contents_as_bytes = static_cast<const uint8_t*>(contents);
+
+  // TODO(crbug.com/pdfium/2155): resolve safety issues.
   auto pFileStream = pDoc->NewIndirect<CPDF_Stream>(
-      DataVector<uint8_t>(contents_as_bytes, contents_as_bytes + len),
+      DataVector<uint8_t>(contents_as_bytes,
+                          UNSAFE_BUFFERS(contents_as_bytes + len)),
       std::move(pFileStreamDict));
+
   auto pEFDict = pFile->AsMutableDictionary()->SetNewFor<CPDF_Dictionary>("EF");
   pEFDict->SetNewFor<CPDF_Reference>("F", pDoc, pFileStream->GetObjNum());
   return true;
diff --git a/fpdfsdk/fpdf_doc.cpp b/fpdfsdk/fpdf_doc.cpp
index 8f2ad24..1dae6cb 100644
--- a/fpdfsdk/fpdf_doc.cpp
+++ b/fpdfsdk/fpdf_doc.cpp
@@ -4,11 +4,6 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
-#if defined(UNSAFE_BUFFERS_BUILD)
-// TODO(crbug.com/pdfium/2153): resolve buffer safety issues.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "public/fpdf_doc.h"
 
 #include <memory>
@@ -120,7 +115,9 @@
   CPDF_Bookmark cBookmark(
       pdfium::WrapRetain(CPDFDictionaryFromFPDFBookmark(bookmark)));
   WideString title = cBookmark.GetTitle();
-  return Utf16EncodeMaybeCopyAndReturnLength(title, buffer, buflen);
+  // SAFETY: required from caller.
+  return UNSAFE_BUFFERS(
+      Utf16EncodeMaybeCopyAndReturnLength(title, buffer, buflen));
 }
 
 FPDF_EXPORT int FPDF_CALLCONV FPDFBookmark_GetCount(FPDF_BOOKMARK bookmark) {
@@ -222,10 +219,11 @@
       type != PDFACTION_LAUNCH) {
     return 0;
   }
-
   CPDF_Action cAction(pdfium::WrapRetain(CPDFDictionaryFromFPDFAction(action)));
   ByteString path = cAction.GetFilePath().ToUTF8();
-  return NulTerminateMaybeCopyAndReturnLength(path, buffer, buflen);
+  // SAFETY: required from caller.
+  return UNSAFE_BUFFERS(
+      NulTerminateMaybeCopyAndReturnLength(path, buffer, buflen));
 }
 
 FPDF_EXPORT unsigned long FPDF_CALLCONV
@@ -271,14 +269,15 @@
     *pNumParams = 0;
     return 0;
   }
-
   CPDF_Dest destination(pdfium::WrapRetain(CPDFArrayFromFPDFDest(dest)));
   const unsigned long nParams =
       pdfium::checked_cast<unsigned long>(destination.GetNumParams());
   DCHECK(nParams <= 4);
   *pNumParams = nParams;
-  for (unsigned long i = 0; i < nParams; ++i)
-    pParams[i] = destination.GetParam(i);
+  for (unsigned long i = 0; i < nParams; ++i) {
+    // TODO(crbug.com/pdfium/2155): resolve safety issues.
+    UNSAFE_BUFFERS(pParams[i] = destination.GetParam(i));
+  }
   return destination.GetZoomMode();
 }
 
@@ -490,8 +489,9 @@
   if (!pValue)
     return 0;
 
-  return NulTerminateMaybeCopyAndReturnLength(pValue->GetString(), buffer,
-                                              buflen);
+  // SAFETY: required from caller.
+  return UNSAFE_BUFFERS(NulTerminateMaybeCopyAndReturnLength(
+      pValue->GetString(), buffer, buflen));
 }
 
 FPDF_EXPORT unsigned long FPDF_CALLCONV FPDF_GetMetaText(FPDF_DOCUMENT document,
@@ -509,7 +509,10 @@
     return 0;
 
   WideString text = pInfo->GetUnicodeTextFor(tag);
-  return Utf16EncodeMaybeCopyAndReturnLength(text, buffer, buflen);
+
+  // SAFETY: required from caller.
+  return UNSAFE_BUFFERS(
+      Utf16EncodeMaybeCopyAndReturnLength(text, buffer, buflen));
 }
 
 FPDF_EXPORT unsigned long FPDF_CALLCONV
@@ -523,7 +526,10 @@
   // CPDF_PageLabel can deal with NULL |document|.
   CPDF_PageLabel label(CPDFDocumentFromFPDFDocument(document));
   std::optional<WideString> str = label.GetLabel(page_index);
-  return str.has_value()
-             ? Utf16EncodeMaybeCopyAndReturnLength(str.value(), buffer, buflen)
-             : 0;
+  if (!str.has_value()) {
+    return 0;
+  }
+  // SAFETY: required from caller.
+  return UNSAFE_BUFFERS(
+      Utf16EncodeMaybeCopyAndReturnLength(str.value(), buffer, buflen));
 }
diff --git a/fpdfsdk/fpdf_editimg.cpp b/fpdfsdk/fpdf_editimg.cpp
index fd44723..7ca3ac5 100644
--- a/fpdfsdk/fpdf_editimg.cpp
+++ b/fpdfsdk/fpdf_editimg.cpp
@@ -4,11 +4,6 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
-#if defined(UNSAFE_BUFFERS_BUILD)
-// TODO(crbug.com/pdfium/2153): resolve buffer safety issues.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "public/fpdf_edit.h"
 
 #include <memory>
@@ -27,6 +22,7 @@
 #include "core/fpdfapi/render/cpdf_imagerenderer.h"
 #include "core/fpdfapi/render/cpdf_rendercontext.h"
 #include "core/fpdfapi/render/cpdf_renderstatus.h"
+#include "core/fxcrt/compiler_specific.h"
 #include "core/fxcrt/notreached.h"
 #include "core/fxcrt/stl_util.h"
 #include "core/fxge/cfx_defaultrenderdevice.h"
@@ -97,9 +93,11 @@
 
   if (pages) {
     for (int index = 0; index < count; index++) {
-      CPDF_Page* pPage = CPDFPageFromFPDFPage(pages[index]);
-      if (pPage)
+      // TODO(crbug.com/pdfium/2155): resolve safety issues.
+      CPDF_Page* pPage = CPDFPageFromFPDFPage(UNSAFE_BUFFERS(pages[index]));
+      if (pPage) {
         pImgObj->GetImage()->ResetCache(pPage);
+      }
     }
   }
 
@@ -177,9 +175,11 @@
 
   if (pages) {
     for (int index = 0; index < count; index++) {
-      CPDF_Page* pPage = CPDFPageFromFPDFPage(pages[index]);
-      if (pPage)
+      // TODO(crbug.com/pdfium/2155): resolve safety issues.
+      CPDF_Page* pPage = CPDFPageFromFPDFPage(UNSAFE_BUFFERS(pages[index]));
+      if (pPage) {
         pImgObj->GetImage()->ResetCache(pPage);
+      }
     }
   }
 
@@ -420,7 +420,9 @@
                             ? pFilter->AsName()->GetString()
                             : pFilter->AsArray()->GetByteStringAt(index);
 
-  return NulTerminateMaybeCopyAndReturnLength(bsFilter, buffer, buflen);
+  // SAFETY: required from caller.
+  return UNSAFE_BUFFERS(
+      NulTerminateMaybeCopyAndReturnLength(bsFilter, buffer, buflen));
 }
 
 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
diff --git a/fpdfsdk/fpdf_editpage.cpp b/fpdfsdk/fpdf_editpage.cpp
index 4ee20b1..7213913 100644
--- a/fpdfsdk/fpdf_editpage.cpp
+++ b/fpdfsdk/fpdf_editpage.cpp
@@ -4,11 +4,6 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
-#if defined(UNSAFE_BUFFERS_BUILD)
-// TODO(crbug.com/pdfium/2153): resolve buffer safety issues.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "public/fpdf_edit.h"
 
 #include <algorithm>
@@ -369,12 +364,13 @@
                         unsigned long* out_buflen) {
   const CPDF_ContentMarkItem* pMarkItem =
       CPDFContentMarkItemFromFPDFPageObjectMark(mark);
-  if (!pMarkItem || !out_buflen)
+  if (!pMarkItem || !out_buflen) {
     return false;
-
-  *out_buflen = Utf16EncodeMaybeCopyAndReturnLength(
+  }
+  // SAFETY: required from caller.
+  *out_buflen = UNSAFE_BUFFERS(Utf16EncodeMaybeCopyAndReturnLength(
       WideString::FromUTF8(pMarkItem->GetName().AsStringView()), buffer,
-      buflen);
+      buflen));
   return true;
 }
 
@@ -405,8 +401,9 @@
   CPDF_DictionaryLocker locker(pParams);
   for (auto& it : locker) {
     if (index == 0) {
-      *out_buflen = Utf16EncodeMaybeCopyAndReturnLength(
-          WideString::FromUTF8(it.first.AsStringView()), buffer, buflen);
+      // SAFETY: required from caller.
+      *out_buflen = UNSAFE_BUFFERS(Utf16EncodeMaybeCopyAndReturnLength(
+          WideString::FromUTF8(it.first.AsStringView()), buffer, buflen));
       return true;
     }
     --index;
@@ -462,8 +459,9 @@
   if (!pObj || !pObj->IsString())
     return false;
 
-  *out_buflen = Utf16EncodeMaybeCopyAndReturnLength(
-      WideString::FromUTF8(pObj->GetString().AsStringView()), buffer, buflen);
+  // SAFETY: required from caller.
+  *out_buflen = UNSAFE_BUFFERS(Utf16EncodeMaybeCopyAndReturnLength(
+      WideString::FromUTF8(pObj->GetString().AsStringView()), buffer, buflen));
   return true;
 }
 
@@ -1016,11 +1014,10 @@
   std::vector<float> dashes;
   if (dash_count > 0) {
     dashes.reserve(dash_count);
-    dashes.assign(dash_array, dash_array + dash_count);
+    // TODO(crbug.com/pdfium/2155): resolve safety issues.
+    dashes.assign(dash_array, UNSAFE_BUFFERS(dash_array + dash_count));
   }
-
   pPageObj->mutable_graph_state().SetLineDash(dashes, phase, 1.0f);
-
   pPageObj->SetDirty(true);
   return true;
 }
diff --git a/fpdfsdk/fpdf_edittext.cpp b/fpdfsdk/fpdf_edittext.cpp
index e9595a4..04d035a 100644
--- a/fpdfsdk/fpdf_edittext.cpp
+++ b/fpdfsdk/fpdf_edittext.cpp
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#if defined(UNSAFE_BUFFERS_BUILD)
-// TODO(crbug.com/pdfium/2153): resolve buffer safety issues.
-#pragma allow_unsafe_buffers
-#endif
-
 #include <map>
 #include <memory>
 #include <sstream>
@@ -34,6 +29,7 @@
 #include "core/fpdftext/cpdf_textpage.h"
 #include "core/fxcrt/check.h"
 #include "core/fxcrt/check_op.h"
+#include "core/fxcrt/compiler_specific.h"
 #include "core/fxcrt/containers/contains.h"
 #include "core/fxcrt/fx_extension.h"
 #include "core/fxcrt/fx_memcpy_wrappers.h"
@@ -621,7 +617,8 @@
   ByteString byte_text;
   if (charcodes) {
     for (size_t i = 0; i < count; ++i) {
-      pTextObj->GetFont()->AppendChar(&byte_text, charcodes[i]);
+      // TODO(crbug.com/pdfium/2155): investigate safety issues.
+      pTextObj->GetFont()->AppendChar(&byte_text, UNSAFE_BUFFERS(charcodes[i]));
     }
   }
   pTextObj->SetText(byte_text);
@@ -638,8 +635,8 @@
       (font_type != FPDF_FONT_TYPE1 && font_type != FPDF_FONT_TRUETYPE)) {
     return nullptr;
   }
-
-  auto span = pdfium::make_span(data, size);
+  // SAFETY: required from caller.
+  auto span = UNSAFE_BUFFERS(pdfium::make_span(data, size));
   auto pFont = std::make_unique<CFX_Font>();
 
   // TODO(npm): Maybe use FT_Get_X11_Font_Format to check format? Otherwise, we
@@ -678,8 +675,8 @@
       cid_to_gid_map_data_size == 0) {
     return nullptr;
   }
-
-  auto font_span = pdfium::make_span(font_data, font_data_size);
+  // SAFETY: required from caller.
+  auto font_span = UNSAFE_BUFFERS(pdfium::make_span(font_data, font_data_size));
   auto font = std::make_unique<CFX_Font>();
 
   // TODO(thestig): Consider checking the font format. See similar comment in
@@ -727,7 +724,9 @@
     return 0;
 
   WideString text = pTextPage->GetTextByObject(pTextObj);
-  return Utf16EncodeMaybeCopyAndReturnLength(text, buffer, length);
+  // SAFETY: required from caller.
+  return UNSAFE_BUFFERS(
+      Utf16EncodeMaybeCopyAndReturnLength(text, buffer, length));
 }
 
 FPDF_EXPORT FPDF_BITMAP FPDF_CALLCONV
diff --git a/fpdfsdk/fpdf_ppo.cpp b/fpdfsdk/fpdf_ppo.cpp
index 33cb246..a4faaa4 100644
--- a/fpdfsdk/fpdf_ppo.cpp
+++ b/fpdfsdk/fpdf_ppo.cpp
@@ -4,11 +4,6 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
-#if defined(UNSAFE_BUFFERS_BUILD)
-// TODO(crbug.com/pdfium/2153): resolve buffer safety issues.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "public/fpdf_ppo.h"
 
 #include <algorithm>
@@ -741,14 +736,13 @@
     std::iota(page_indices_vec.begin(), page_indices_vec.end(), 0);
     return exporter.ExportPage(page_indices_vec, index);
   }
-
-  if (length == 0)
+  if (length == 0) {
     return false;
-
-  return exporter.ExportPage(
-      pdfium::make_span(reinterpret_cast<const uint32_t*>(page_indices),
-                        length),
-      index);
+  }
+  // TODO(crbug.com/pdfium/2155): investigate safety issues.
+  auto page_span = UNSAFE_BUFFERS(pdfium::make_span(
+      reinterpret_cast<const uint32_t*>(page_indices), length));
+  return exporter.ExportPage(page_span, index);
 }
 
 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDF_ImportPages(FPDF_DOCUMENT dest_doc,
diff --git a/fpdfsdk/fpdf_signature.cpp b/fpdfsdk/fpdf_signature.cpp
index c7c41a7..2bcfa8b 100644
--- a/fpdfsdk/fpdf_signature.cpp
+++ b/fpdfsdk/fpdf_signature.cpp
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#if defined(UNSAFE_BUFFERS_BUILD)
-// TODO(crbug.com/pdfium/2153): resolve buffer safety issues.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "public/fpdf_signature.h"
 
 #include <utility>
@@ -121,8 +116,10 @@
   const unsigned long byte_range_len =
       fxcrt::CollectionSize<unsigned long>(*byte_range);
   if (buffer && length >= byte_range_len) {
-    for (size_t i = 0; i < byte_range_len; ++i)
-      buffer[i] = byte_range->GetIntegerAt(i);
+    for (size_t i = 0; i < byte_range_len; ++i) {
+      // TODO(crbug.com/pdfium/2155): resolve safety issue.
+      UNSAFE_BUFFERS(buffer[i] = byte_range->GetIntegerAt(i));
+    }
   }
   return byte_range_len;
 }
@@ -142,7 +139,10 @@
     return 0;
 
   ByteString sub_filter = value_dict->GetNameFor("SubFilter");
-  return NulTerminateMaybeCopyAndReturnLength(sub_filter, buffer, length);
+
+  // SAFETY: required from caller.
+  return UNSAFE_BUFFERS(
+      NulTerminateMaybeCopyAndReturnLength(sub_filter, buffer, length));
 }
 
 FPDF_EXPORT unsigned long FPDF_CALLCONV
@@ -163,8 +163,9 @@
   if (!obj || !obj->IsString())
     return 0;
 
-  return Utf16EncodeMaybeCopyAndReturnLength(obj->GetUnicodeText(), buffer,
-                                             length);
+  // SAFETY: required from caller.
+  return UNSAFE_BUFFERS(Utf16EncodeMaybeCopyAndReturnLength(
+      obj->GetUnicodeText(), buffer, length));
 }
 
 FPDF_EXPORT unsigned long FPDF_CALLCONV
@@ -185,7 +186,9 @@
   if (!obj || !obj->IsString())
     return 0;
 
-  return NulTerminateMaybeCopyAndReturnLength(obj->GetString(), buffer, length);
+  // SAFETY: required from caller.
+  return UNSAFE_BUFFERS(
+      NulTerminateMaybeCopyAndReturnLength(obj->GetString(), buffer, length));
 }
 
 FPDF_EXPORT unsigned int FPDF_CALLCONV
diff --git a/fpdfsdk/fpdf_view.cpp b/fpdfsdk/fpdf_view.cpp
index 3f9a7f0..7955f2d 100644
--- a/fpdfsdk/fpdf_view.cpp
+++ b/fpdfsdk/fpdf_view.cpp
@@ -4,11 +4,6 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
-#if defined(UNSAFE_BUFFERS_BUILD)
-// TODO(crbug.com/pdfium/2153): resolve buffer safety issues.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "public/fpdfview.h"
 
 #include <memory>
@@ -349,21 +344,22 @@
   if (size < 0) {
     return nullptr;
   }
-
-  return LoadDocumentImpl(
-      pdfium::MakeRetain<CFX_ReadOnlySpanStream>(pdfium::make_span(
-          static_cast<const uint8_t*>(data_buf), static_cast<size_t>(size))),
-      password);
+  // SAFETY: required from caller.
+  auto data_span = UNSAFE_BUFFERS(pdfium::make_span(
+      static_cast<const uint8_t*>(data_buf), static_cast<size_t>(size)));
+  return LoadDocumentImpl(pdfium::MakeRetain<CFX_ReadOnlySpanStream>(data_span),
+                          password);
 }
 
 FPDF_EXPORT FPDF_DOCUMENT FPDF_CALLCONV
 FPDF_LoadMemDocument64(const void* data_buf,
                        size_t size,
                        FPDF_BYTESTRING password) {
-  return LoadDocumentImpl(
-      pdfium::MakeRetain<CFX_ReadOnlySpanStream>(
-          pdfium::make_span(static_cast<const uint8_t*>(data_buf), size)),
-      password);
+  // SAFETY: required from caller.
+  auto data_span = UNSAFE_BUFFERS(
+      pdfium::make_span(static_cast<const uint8_t*>(data_buf), size));
+  return LoadDocumentImpl(pdfium::MakeRetain<CFX_ReadOnlySpanStream>(data_span),
+                          password);
 }
 
 FPDF_EXPORT FPDF_DOCUMENT FPDF_CALLCONV
@@ -1107,10 +1103,12 @@
 
   CPDF_ViewerPreferences viewRef(pDoc);
   std::optional<ByteString> bsVal = viewRef.GenericName(key);
-  if (!bsVal.has_value())
+  if (!bsVal.has_value()) {
     return 0;
-
-  return NulTerminateMaybeCopyAndReturnLength(bsVal.value(), buffer, length);
+  }
+  // SAFETY: required from caller.
+  return UNSAFE_BUFFERS(
+      NulTerminateMaybeCopyAndReturnLength(bsVal.value(), buffer, length));
 }
 
 FPDF_EXPORT FPDF_DWORD FPDF_CALLCONV
@@ -1312,11 +1310,12 @@
 
   std::vector<XFAPacket> xfa_packets =
       GetXFAPackets(GetXFAEntryFromDocument(doc));
-  if (static_cast<size_t>(index) >= xfa_packets.size())
+  if (static_cast<size_t>(index) >= xfa_packets.size()) {
     return 0;
-
-  return NulTerminateMaybeCopyAndReturnLength(xfa_packets[index].name, buffer,
-                                              buflen);
+  }
+  // TODO(crbug.com/pdfium/2155): resolve safety issues.
+  return UNSAFE_BUFFERS(NulTerminateMaybeCopyAndReturnLength(
+      xfa_packets[index].name, buffer, buflen));
 }
 
 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
@@ -1356,7 +1355,8 @@
   const unsigned long trailer_ends_len =
       fxcrt::CollectionSize<unsigned long>(trailer_ends);
   if (buffer && length >= trailer_ends_len) {
-    fxcrt::spancpy(pdfium::make_span(buffer, length),
+    // SAFETY: required from caller.
+    fxcrt::spancpy(UNSAFE_BUFFERS(pdfium::make_span(buffer, length)),
                    pdfium::make_span(trailer_ends));
   }