Pass spans further down into jpx/jbig2 decoders

Change-Id: Ia7c8de01e52872d56a853a4705930c34c09c1431
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/100990
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/page/cpdf_dib.cpp b/core/fpdfapi/page/cpdf_dib.cpp
index 00f5bfd..6d1e66c 100644
--- a/core/fpdfapi/page/cpdf_dib.cpp
+++ b/core/fpdfapi/page/cpdf_dib.cpp
@@ -294,8 +294,7 @@
     iDecodeStatus = Jbig2Decoder::StartDecode(
         m_pJbig2Context.get(), m_pDocument->GetOrCreateCodecContext(), m_Width,
         m_Height, pSrcSpan, nSrcKey, pGlobalSpan, nGlobalKey,
-        m_pCachedBitmap->GetBuffer().data(), m_pCachedBitmap->GetPitch(),
-        pPause);
+        m_pCachedBitmap->GetBuffer(), m_pCachedBitmap->GetPitch(), pPause);
   } else {
     iDecodeStatus = Jbig2Decoder::ContinueDecode(m_pJbig2Context.get(), pPause);
   }
@@ -646,8 +645,8 @@
     return nullptr;
 
   result_bitmap->Clear(0xFFFFFFFF);
-  if (!decoder->Decode(result_bitmap->GetBuffer().data(),
-                       result_bitmap->GetPitch(), swap_rgb)) {
+  if (!decoder->Decode(result_bitmap->GetBuffer(), result_bitmap->GetPitch(),
+                       swap_rgb)) {
     return nullptr;
   }
 
diff --git a/core/fxcodec/jbig2/JBig2_Context.cpp b/core/fxcodec/jbig2/JBig2_Context.cpp
index d7310c4..31b6f72 100644
--- a/core/fxcodec/jbig2/JBig2_Context.cpp
+++ b/core/fxcodec/jbig2/JBig2_Context.cpp
@@ -127,7 +127,7 @@
   return JBig2_Result::kSuccess;
 }
 
-bool CJBig2_Context::GetFirstPage(uint8_t* pBuf,
+bool CJBig2_Context::GetFirstPage(pdfium::span<uint8_t> pBuf,
                                   int32_t width,
                                   int32_t height,
                                   int32_t stride,
diff --git a/core/fxcodec/jbig2/JBig2_Context.h b/core/fxcodec/jbig2/JBig2_Context.h
index 6a8e828..8c8897e 100644
--- a/core/fxcodec/jbig2/JBig2_Context.h
+++ b/core/fxcodec/jbig2/JBig2_Context.h
@@ -40,7 +40,7 @@
 
   static bool HuffmanAssignCode(JBig2HuffmanCode* SBSYMCODES, uint32_t NTEMP);
 
-  bool GetFirstPage(uint8_t* pBuf,
+  bool GetFirstPage(pdfium::span<uint8_t> pBuf,
                     int32_t width,
                     int32_t height,
                     int32_t stride,
diff --git a/core/fxcodec/jbig2/JBig2_Image.cpp b/core/fxcodec/jbig2/JBig2_Image.cpp
index 8004a05..773f6ac 100644
--- a/core/fxcodec/jbig2/JBig2_Image.cpp
+++ b/core/fxcodec/jbig2/JBig2_Image.cpp
@@ -62,7 +62,7 @@
 CJBig2_Image::CJBig2_Image(int32_t w,
                            int32_t h,
                            int32_t stride,
-                           uint8_t* pBuf) {
+                           pdfium::span<uint8_t> pBuf) {
   if (w < 0 || h < 0)
     return;
 
@@ -77,7 +77,7 @@
   m_nWidth = w;
   m_nHeight = h;
   m_nStride = stride;
-  m_pData.Reset(pBuf);
+  m_pData.Reset(pBuf.data());
 }
 
 CJBig2_Image::CJBig2_Image(const CJBig2_Image& other)
diff --git a/core/fxcodec/jbig2/JBig2_Image.h b/core/fxcodec/jbig2/JBig2_Image.h
index 090d338..4f751f4 100644
--- a/core/fxcodec/jbig2/JBig2_Image.h
+++ b/core/fxcodec/jbig2/JBig2_Image.h
@@ -12,6 +12,7 @@
 #include "core/fxcodec/jbig2/JBig2_Define.h"
 #include "core/fxcrt/fx_memory_wrappers.h"
 #include "core/fxcrt/maybe_owned.h"
+#include "third_party/base/span.h"
 
 struct FX_RECT;
 
@@ -26,7 +27,10 @@
 class CJBig2_Image {
  public:
   CJBig2_Image(int32_t w, int32_t h);
-  CJBig2_Image(int32_t w, int32_t h, int32_t stride, uint8_t* pBuf);
+  CJBig2_Image(int32_t w,
+               int32_t h,
+               int32_t stride,
+               pdfium::span<uint8_t> pBuf);
   CJBig2_Image(const CJBig2_Image& other);
   ~CJBig2_Image();
 
diff --git a/core/fxcodec/jbig2/JBig2_Image_unittest.cpp b/core/fxcodec/jbig2/JBig2_Image_unittest.cpp
index 2222e54..d76ab8a 100644
--- a/core/fxcodec/jbig2/JBig2_Image_unittest.cpp
+++ b/core/fxcodec/jbig2/JBig2_Image_unittest.cpp
@@ -192,60 +192,54 @@
 }
 
 TEST(fxcodec, JBig2SubImage) {
+  // clang-format off
   // 1-px wide rectangle in image.
-  uint8_t pattern[5][8] = {
-      {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-      {0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00},
-      {0x00, 0x01, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00},
-      {0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00},
-      {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+  uint8_t pattern[40] = {
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x01, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   };
 
   // 1-px wide rectangle in image, offset 2 in x.
-  uint8_t pattern20[5][8] = {
-      {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-      {0x00, 0x07, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
-      {0x00, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00},
-      {0x00, 0x07, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
-      {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+  uint8_t pattern20[40] = {
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x07, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x07, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   };
 
   // 1-px wide rectangle in image, offset 2 in x and y, padded.
-  uint8_t pattern22[5][8] = {
-      {0x00, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00},
-      {0x00, 0x07, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
-      {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-      {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-      {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+  uint8_t pattern22[40] = {
+      0x00, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x07, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   };
 
   // 1-px wide rectangle in image, offset 16 in x, 1 in y, padded.
-  uint8_t pattern161[5][8] = {
-      {0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-      {0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-      {0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-      {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-      {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+  uint8_t pattern161[40] = {
+      0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   };
+  // clang-format on
 
   // Image size a nice clean power of two.
-  auto img32 = std::make_unique<CJBig2_Image>(
-      32, 5, 8, reinterpret_cast<uint8_t*>(pattern));
+  auto img32 = std::make_unique<CJBig2_Image>(32, 5, 8, pattern);
 
   // Image size not a nice clean value.
-  auto img37 = std::make_unique<CJBig2_Image>(
-      37, 5, 8, reinterpret_cast<uint8_t*>(pattern));
+  auto img37 = std::make_unique<CJBig2_Image>(37, 5, 8, pattern);
 
   // Expected results to check against.
-  auto expected20 = std::make_unique<CJBig2_Image>(
-      30, 5, 8, reinterpret_cast<uint8_t*>(pattern20));
-
-  auto expected22 = std::make_unique<CJBig2_Image>(
-      30, 5, 8, reinterpret_cast<uint8_t*>(pattern22));
-
-  auto expected161 = std::make_unique<CJBig2_Image>(
-      25, 5, 8, reinterpret_cast<uint8_t*>(pattern161));
-
+  auto expected20 = std::make_unique<CJBig2_Image>(30, 5, 8, pattern20);
+  auto expected22 = std::make_unique<CJBig2_Image>(30, 5, 8, pattern22);
+  auto expected161 = std::make_unique<CJBig2_Image>(25, 5, 8, pattern161);
   auto expected_zeros = std::make_unique<CJBig2_Image>(32, 5);
 
   // Empty subimage.
@@ -315,24 +309,23 @@
 }
 
 TEST(fxcodec, JBig2CopyLine) {
+  // clang-format off
   // Horizontal line in image.
-  uint8_t pattern[3][8] = {
-      {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-      {0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00},
-      {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+  uint8_t pattern[24] = {
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   };
 
-  uint8_t expected_pattern[3][8] = {
-      {0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00},
-      {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-      {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+  uint8_t expected_pattern[24] = {
+      0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   };
+  // clang-format on
 
-  auto img = std::make_unique<CJBig2_Image>(
-      37, 3, 8, reinterpret_cast<uint8_t*>(pattern));
-
-  auto expected = std::make_unique<CJBig2_Image>(
-      37, 3, 8, reinterpret_cast<uint8_t*>(expected_pattern));
+  auto img = std::make_unique<CJBig2_Image>(37, 3, 8, pattern);
+  auto expected = std::make_unique<CJBig2_Image>(37, 3, 8, expected_pattern);
 
   // Shuffle.
   img->CopyLine(2, 1);
diff --git a/core/fxcodec/jbig2/jbig2_decoder.cpp b/core/fxcodec/jbig2/jbig2_decoder.cpp
index 82f6a47..0b95382 100644
--- a/core/fxcodec/jbig2/jbig2_decoder.cpp
+++ b/core/fxcodec/jbig2/jbig2_decoder.cpp
@@ -10,6 +10,7 @@
 
 #include "core/fxcodec/jbig2/JBig2_Context.h"
 #include "core/fxcodec/jbig2/JBig2_DocumentContext.h"
+#include "core/fxcrt/span_util.h"
 
 namespace fxcodec {
 
@@ -47,7 +48,7 @@
     uint64_t src_key,
     pdfium::span<const uint8_t> global_span,
     uint64_t global_key,
-    uint8_t* dest_buf,
+    pdfium::span<uint8_t> dest_buf,
     uint32_t dest_pitch,
     PauseIndicatorIface* pPause) {
   pJbig2Context->m_width = width;
@@ -56,9 +57,9 @@
   pJbig2Context->m_nSrcKey = src_key;
   pJbig2Context->m_pGlobalSpan = global_span;
   pJbig2Context->m_nGlobalKey = global_key;
-  pJbig2Context->m_dest_buf = dest_buf;
+  pJbig2Context->m_dest_buf = dest_buf.data();
   pJbig2Context->m_dest_pitch = dest_pitch;
-  memset(dest_buf, 0, height * dest_pitch);
+  fxcrt::spanset(dest_buf.first(height * dest_pitch), 0);
   pJbig2Context->m_pContext =
       CJBig2_Context::Create(global_span, global_key, src_span, src_key,
                              pJBig2DocumentContext->GetSymbolDictCache());
diff --git a/core/fxcodec/jbig2/jbig2_decoder.h b/core/fxcodec/jbig2/jbig2_decoder.h
index a797a81..0a94f5d 100644
--- a/core/fxcodec/jbig2/jbig2_decoder.h
+++ b/core/fxcodec/jbig2/jbig2_decoder.h
@@ -45,7 +45,7 @@
       uint64_t src_key,
       pdfium::span<const uint8_t> global_span,
       uint64_t global_key,
-      uint8_t* dest_buf,
+      pdfium::span<uint8_t> dest_buf,
       uint32_t dest_pitch,
       PauseIndicatorIface* pPause);
 
diff --git a/core/fxcodec/jpx/cjpx_decoder.cpp b/core/fxcodec/jpx/cjpx_decoder.cpp
index e18fb05..4d735c9 100644
--- a/core/fxcodec/jpx/cjpx_decoder.cpp
+++ b/core/fxcodec/jpx/cjpx_decoder.cpp
@@ -15,6 +15,7 @@
 
 #include "core/fxcodec/jpx/jpx_decode_utils.h"
 #include "core/fxcrt/fx_safe_types.h"
+#include "core/fxcrt/span_util.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/base/cxx17_backports.h"
 #include "third_party/base/ptr_util.h"
@@ -509,18 +510,20 @@
           m_Image->color_space};
 }
 
-bool CJPX_Decoder::Decode(uint8_t* dest_buf, uint32_t pitch, bool swap_rgb) {
+bool CJPX_Decoder::Decode(pdfium::span<uint8_t> dest_buf,
+                          uint32_t pitch,
+                          bool swap_rgb) {
   if (pitch < ((m_Image->comps[0].w * 8 * m_Image->numcomps + 31) >> 5) << 2)
     return false;
 
   if (swap_rgb && m_Image->numcomps < 3)
     return false;
 
-  memset(dest_buf, 0xff, m_Image->comps[0].h * pitch);
+  fxcrt::spanset(dest_buf.first(m_Image->comps[0].h * pitch), 0xff);
   std::vector<uint8_t*> channel_bufs(m_Image->numcomps);
   std::vector<int> adjust_comps(m_Image->numcomps);
   for (uint32_t i = 0; i < m_Image->numcomps; i++) {
-    channel_bufs[i] = dest_buf + i;
+    channel_bufs[i] = dest_buf.subspan(i).data();
     adjust_comps[i] = m_Image->comps[i].prec - 8;
     if (i > 0) {
       if (m_Image->comps[i].dx != m_Image->comps[i - 1].dx ||
diff --git a/core/fxcodec/jpx/cjpx_decoder.h b/core/fxcodec/jpx/cjpx_decoder.h
index b7f838b..7045cdf 100644
--- a/core/fxcodec/jpx/cjpx_decoder.h
+++ b/core/fxcodec/jpx/cjpx_decoder.h
@@ -50,7 +50,7 @@
   bool StartDecode();
 
   // |swap_rgb| can only be set for images with 3 or more components.
-  bool Decode(uint8_t* dest_buf, uint32_t pitch, bool swap_rgb);
+  bool Decode(pdfium::span<uint8_t> dest_buf, uint32_t pitch, bool swap_rgb);
 
  private:
   // Use Create() to instantiate.
diff --git a/testing/fuzzers/pdf_codec_jbig2_fuzzer.cc b/testing/fuzzers/pdf_codec_jbig2_fuzzer.cc
index ec74f16..59eda76 100644
--- a/testing/fuzzers/pdf_codec_jbig2_fuzzer.cc
+++ b/testing/fuzzers/pdf_codec_jbig2_fuzzer.cc
@@ -38,7 +38,7 @@
   Jbig2Context jbig2_context;
   FXCODEC_STATUS status = Jbig2Decoder::StartDecode(
       &jbig2_context, &document_context, width, height, {data, size}, 1, {}, 0,
-      bitmap->GetBuffer().data(), bitmap->GetPitch(), nullptr);
+      bitmap->GetBuffer(), bitmap->GetPitch(), nullptr);
 
   while (status == FXCODEC_STATUS::kDecodeToBeContinued)
     status = Jbig2Decoder::ContinueDecode(&jbig2_context, nullptr);
diff --git a/testing/fuzzers/pdf_jpx_fuzzer.cc b/testing/fuzzers/pdf_jpx_fuzzer.cc
index bf191ab..ef88c7f 100644
--- a/testing/fuzzers/pdf_jpx_fuzzer.cc
+++ b/testing/fuzzers/pdf_jpx_fuzzer.cc
@@ -69,7 +69,7 @@
           static_cast<uint32_t>(bitmap->GetHeight()))
     return 0;
 
-  decoder->Decode(bitmap->GetBuffer().data(), bitmap->GetPitch(),
+  decoder->Decode(bitmap->GetBuffer(), bitmap->GetPitch(),
                   /*swap_rgb=*/false);
 
   return 0;