Use more spans in streams, part 5

Change-Id: Iacddd5c2b750648f236990ee066a4734cd92367c
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/100535
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/parser/cpdf_stream.cpp b/core/fpdfapi/parser/cpdf_stream.cpp
index 12cfcf2..bdcb5f6 100644
--- a/core/fpdfapi/parser/cpdf_stream.cpp
+++ b/core/fpdfapi/parser/cpdf_stream.cpp
@@ -137,12 +137,10 @@
            static_cast<size_t>(stream->tellp())});
 }
 
-bool CPDF_Stream::ReadRawData(FX_FILESIZE offset,
-                              uint8_t* buf,
-                              size_t size) const {
+bool CPDF_Stream::ReadRawData(pdfium::span<uint8_t> buffer) const {
   CHECK(IsFileBased());
   return absl::get<RetainPtr<IFX_SeekableReadStream>>(data_)->ReadBlockAtOffset(
-      {buf, size}, offset);
+      buffer, 0);
 }
 
 bool CPDF_Stream::HasFilter() const {
diff --git a/core/fpdfapi/parser/cpdf_stream.h b/core/fpdfapi/parser/cpdf_stream.h
index a3974b2..5066880 100644
--- a/core/fpdfapi/parser/cpdf_stream.h
+++ b/core/fpdfapi/parser/cpdf_stream.h
@@ -56,7 +56,7 @@
                           RetainPtr<CPDF_Dictionary> pDict);
 
   // Can only be called when a stream is not memory-based.
-  bool ReadRawData(FX_FILESIZE offset, uint8_t* pBuf, size_t buf_size) const;
+  bool ReadRawData(pdfium::span<uint8_t> buffer) const;
 
   bool IsUninitialized() const { return data_.index() == 0; }
   bool IsFileBased() const { return data_.index() == 1; }
diff --git a/core/fpdfapi/parser/cpdf_stream_acc.cpp b/core/fpdfapi/parser/cpdf_stream_acc.cpp
index 8a11ff5..3f82237 100644
--- a/core/fpdfapi/parser/cpdf_stream_acc.cpp
+++ b/core/fpdfapi/parser/cpdf_stream_acc.cpp
@@ -171,7 +171,7 @@
 
   DataVector<uint8_t> result(m_pStream->GetRawSize());
   DCHECK(!result.empty());
-  if (!m_pStream->ReadRawData(0, result.data(), result.size()))
+  if (!m_pStream->ReadRawData(result))
     return DataVector<uint8_t>();
   return result;
 }
diff --git a/fpdfsdk/cpdfsdk_helpers.cpp b/fpdfsdk/cpdfsdk_helpers.cpp
index f43b692..c548420 100644
--- a/fpdfsdk/cpdfsdk_helpers.cpp
+++ b/fpdfsdk/cpdfsdk_helpers.cpp
@@ -20,6 +20,7 @@
 #include "core/fpdfdoc/cpdf_annot.h"
 #include "core/fpdfdoc/cpdf_interactiveform.h"
 #include "core/fpdfdoc/cpdf_metadata.h"
+#include "core/fxcrt/span_util.h"
 #include "core/fxcrt/unowned_ptr.h"
 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
 #include "third_party/base/check.h"
@@ -53,26 +54,22 @@
   return form && form->GetArrayFor("XFA");
 }
 
-unsigned long GetStreamMaybeCopyAndReturnLengthImpl(const CPDF_Stream* stream,
-                                                    void* buffer,
-                                                    unsigned long buflen,
-                                                    bool decode) {
+unsigned long GetStreamMaybeCopyAndReturnLengthImpl(
+    RetainPtr<const CPDF_Stream> stream,
+    pdfium::span<uint8_t> buffer,
+    bool decode) {
   DCHECK(stream);
-  auto stream_acc =
-      pdfium::MakeRetain<CPDF_StreamAcc>(pdfium::WrapRetain(stream));
-
+  auto stream_acc = pdfium::MakeRetain<CPDF_StreamAcc>(std::move(stream));
   if (decode)
     stream_acc->LoadAllDataFiltered();
   else
     stream_acc->LoadAllDataRaw();
 
-  const auto stream_data_size = stream_acc->GetSize();
-  if (!buffer || buflen < stream_data_size)
-    return stream_data_size;
+  pdfium::span<const uint8_t> stream_data_span = stream_acc->GetSpan();
+  if (!buffer.empty() && buffer.size() <= stream_data_span.size())
+    fxcrt::spancpy(buffer, stream_data_span);
 
-  pdfium::span<const uint8_t> span = stream_acc->GetSpan();
-  memcpy(buffer, span.data(), span.size());
-  return stream_data_size;
+  return pdfium::base::checked_cast<unsigned long>(stream_data_span.size());
 }
 
 #ifdef PDF_ENABLE_XFA
@@ -305,17 +302,17 @@
   return len;
 }
 
-unsigned long GetRawStreamMaybeCopyAndReturnLength(const CPDF_Stream* stream,
-                                                   void* buffer,
-                                                   unsigned long buflen) {
-  return GetStreamMaybeCopyAndReturnLengthImpl(stream, buffer, buflen,
+unsigned long GetRawStreamMaybeCopyAndReturnLength(
+    RetainPtr<const CPDF_Stream> stream,
+    pdfium::span<uint8_t> buffer) {
+  return GetStreamMaybeCopyAndReturnLengthImpl(std::move(stream), buffer,
                                                /*decode=*/false);
 }
 
-unsigned long DecodeStreamMaybeCopyAndReturnLength(const CPDF_Stream* stream,
-                                                   void* buffer,
-                                                   unsigned long buflen) {
-  return GetStreamMaybeCopyAndReturnLengthImpl(stream, buffer, buflen,
+unsigned long DecodeStreamMaybeCopyAndReturnLength(
+    RetainPtr<const CPDF_Stream> stream,
+    pdfium::span<uint8_t> buffer) {
+  return GetStreamMaybeCopyAndReturnLengthImpl(std::move(stream), buffer,
                                                /*decode=*/true);
 }
 
diff --git a/fpdfsdk/cpdfsdk_helpers.h b/fpdfsdk/cpdfsdk_helpers.h
index 6925626..076cac7 100644
--- a/fpdfsdk/cpdfsdk_helpers.h
+++ b/fpdfsdk/cpdfsdk_helpers.h
@@ -276,19 +276,19 @@
 
 // Returns the length of the raw stream data from |stream|. The raw data is the
 // stream's data as stored in the PDF without applying any filters. If |buffer|
-// is non-nullptr and |buflen| is large enough to contain the raw data, then
+// is non-empty and its length is large enough to contain the raw data, then
 // the raw data is copied into |buffer|.
-unsigned long GetRawStreamMaybeCopyAndReturnLength(const CPDF_Stream* stream,
-                                                   void* buffer,
-                                                   unsigned long buflen);
+unsigned long GetRawStreamMaybeCopyAndReturnLength(
+    RetainPtr<const CPDF_Stream> stream,
+    pdfium::span<uint8_t> buffer);
 
 // Return the length of the decoded stream data of |stream|. The decoded data is
 // the uncompressed stream data, i.e. the raw stream data after having all
-// filters applied. If |buffer| is non-nullptr and |buflen| is large enough to
+// filters applied. If |buffer| is non-empty and its length is large enough to
 // contain the decoded data, then the decoded data is copied into |buffer|.
-unsigned long DecodeStreamMaybeCopyAndReturnLength(const CPDF_Stream* stream,
-                                                   void* buffer,
-                                                   unsigned long buflen);
+unsigned long DecodeStreamMaybeCopyAndReturnLength(
+    RetainPtr<const CPDF_Stream> stream,
+    pdfium::span<uint8_t> buffer);
 
 void SetPDFSandboxPolicy(FPDF_DWORD policy, FPDF_BOOL enable);
 FPDF_BOOL IsPDFSandboxPolicyEnabled(FPDF_DWORD policy);
diff --git a/fpdfsdk/fpdf_attachment.cpp b/fpdfsdk/fpdf_attachment.cpp
index 44367e8..04aed02 100644
--- a/fpdfsdk/fpdf_attachment.cpp
+++ b/fpdfsdk/fpdf_attachment.cpp
@@ -274,7 +274,8 @@
   if (!pFileStream)
     return false;
 
-  *out_buflen =
-      DecodeStreamMaybeCopyAndReturnLength(pFileStream.Get(), buffer, buflen);
+  *out_buflen = DecodeStreamMaybeCopyAndReturnLength(
+      std::move(pFileStream),
+      {static_cast<uint8_t*>(buffer), static_cast<size_t>(buflen)});
   return true;
 }
diff --git a/fpdfsdk/fpdf_editimg.cpp b/fpdfsdk/fpdf_editimg.cpp
index f4b0d3b..05d1ff7 100644
--- a/fpdfsdk/fpdf_editimg.cpp
+++ b/fpdfsdk/fpdf_editimg.cpp
@@ -282,7 +282,9 @@
   if (!pImgStream)
     return 0;
 
-  return DecodeStreamMaybeCopyAndReturnLength(pImgStream.Get(), buffer, buflen);
+  return DecodeStreamMaybeCopyAndReturnLength(
+      std::move(pImgStream),
+      {static_cast<uint8_t*>(buffer), static_cast<size_t>(buflen)});
 }
 
 FPDF_EXPORT unsigned long FPDF_CALLCONV
@@ -301,7 +303,9 @@
   if (!pImgStream)
     return 0;
 
-  return GetRawStreamMaybeCopyAndReturnLength(pImgStream.Get(), buffer, buflen);
+  return GetRawStreamMaybeCopyAndReturnLength(
+      std::move(pImgStream),
+      {static_cast<uint8_t*>(buffer), static_cast<size_t>(buflen)});
 }
 
 FPDF_EXPORT int FPDF_CALLCONV
diff --git a/fpdfsdk/fpdf_thumbnail.cpp b/fpdfsdk/fpdf_thumbnail.cpp
index 5d3d08d..0f1331d 100644
--- a/fpdfsdk/fpdf_thumbnail.cpp
+++ b/fpdfsdk/fpdf_thumbnail.cpp
@@ -40,7 +40,9 @@
   if (!thumb_stream)
     return 0u;
 
-  return DecodeStreamMaybeCopyAndReturnLength(thumb_stream, buffer, buflen);
+  return DecodeStreamMaybeCopyAndReturnLength(
+      std::move(thumb_stream),
+      {static_cast<uint8_t*>(buffer), static_cast<size_t>(buflen)});
 }
 
 FPDF_EXPORT unsigned long FPDF_CALLCONV
@@ -52,7 +54,9 @@
   if (!thumb_stream)
     return 0u;
 
-  return GetRawStreamMaybeCopyAndReturnLength(thumb_stream, buffer, buflen);
+  return GetRawStreamMaybeCopyAndReturnLength(
+      std::move(thumb_stream),
+      {static_cast<uint8_t*>(buffer), static_cast<size_t>(buflen)});
 }
 
 FPDF_EXPORT FPDF_BITMAP FPDF_CALLCONV
diff --git a/fpdfsdk/fpdf_view.cpp b/fpdfsdk/fpdf_view.cpp
index 8f244a9..55eef66 100644
--- a/fpdfsdk/fpdf_view.cpp
+++ b/fpdfsdk/fpdf_view.cpp
@@ -1275,8 +1275,9 @@
   if (static_cast<size_t>(index) >= xfa_packets.size())
     return false;
 
-  *out_buflen = DecodeStreamMaybeCopyAndReturnLength(xfa_packets[index].data,
-                                                     buffer, buflen);
+  *out_buflen = DecodeStreamMaybeCopyAndReturnLength(
+      xfa_packets[index].data,
+      {static_cast<uint8_t*>(buffer), static_cast<size_t>(buflen)});
   return true;
 }