Make PDF_DataDecode()'s buffer out parameter a std::unique_ptr.

Change-Id: Id8f7473c590ef94799d0dd29f5de790a453c86f6
Reviewed-on: https://pdfium-review.googlesource.com/c/42603
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/parser/cpdf_stream_acc.cpp b/core/fpdfapi/parser/cpdf_stream_acc.cpp
index c87e404..6516a2f 100644
--- a/core/fpdfapi/parser/cpdf_stream_acc.cpp
+++ b/core/fpdfapi/parser/cpdf_stream_acc.cpp
@@ -115,7 +115,7 @@
     pSrcData = std::move(pTempSrcData);
   }
 
-  uint8_t* pDecodedData = nullptr;
+  std::unique_ptr<uint8_t, FxFreeDeleter> pDecodedData;
   uint32_t dwDecodedSize = 0;
   if (!PDF_DataDecode({pSrcData.Get(), dwSrcSize}, m_pStream->GetDict(),
                       estimated_size, bImageAcc, &pDecodedData, &dwDecodedSize,
@@ -125,16 +125,13 @@
     return;
   }
 
-  if (!pDecodedData)
-    return;
-
-  if (pDecodedData == pSrcData.Get()) {
+  if (pDecodedData) {
+    ASSERT(pDecodedData.get() != pSrcData.Get());
+    m_pData = std::move(pDecodedData);
+    m_dwSize = dwDecodedSize;
+  } else {
     m_pData = std::move(pSrcData);
     m_dwSize = dwSrcSize;
-  } else {
-    std::unique_ptr<uint8_t, FxFreeDeleter> p(pDecodedData);
-    m_pData = std::move(p);
-    m_dwSize = dwDecodedSize;
   }
 }
 
diff --git a/core/fpdfapi/parser/fpdf_parser_decode.cpp b/core/fpdfapi/parser/fpdf_parser_decode.cpp
index 2f73b3a..a581dcc 100644
--- a/core/fpdfapi/parser/fpdf_parser_decode.cpp
+++ b/core/fpdfapi/parser/fpdf_parser_decode.cpp
@@ -362,17 +362,16 @@
                     const CPDF_Dictionary* pDict,
                     uint32_t last_estimated_size,
                     bool bImageAcc,
-                    uint8_t** dest_buf,
+                    std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
                     uint32_t* dest_size,
                     ByteString* ImageEncoding,
                     UnownedPtr<const CPDF_Dictionary>* pImageParams) {
-  const CPDF_Object* pDecoder =
-      pDict ? pDict->GetDirectObjectFor("Filter") : nullptr;
+  const CPDF_Object* pDecoder = pDict->GetDirectObjectFor("Filter");
   if (!pDecoder || (!pDecoder->IsArray() && !pDecoder->IsName()))
     return false;
 
   const CPDF_Object* pParams =
-      pDict ? pDict->GetDirectObjectFor(pdfium::stream::kDecodeParms) : nullptr;
+      pDict->GetDirectObjectFor(pdfium::stream::kDecodeParms);
 
   std::vector<std::pair<ByteString, const CPDF_Object*>> DecoderArray;
   if (const CPDF_Array* pDecoders = pDecoder->AsArray()) {
@@ -389,14 +388,15 @@
     DecoderArray.push_back(
         {pDecoder->GetString(), pParams ? pParams->GetDict() : nullptr});
   }
-  pdfium::span<uint8_t> last_span(const_cast<uint8_t*>(src_span.data()),
-                                  src_span.size());
+
+  pdfium::span<const uint8_t> last_span = src_span;
+  std::unique_ptr<uint8_t, FxFreeDeleter> result;
   size_t nSize = DecoderArray.size();
   for (size_t i = 0; i < nSize; ++i) {
     int estimated_size = i == nSize - 1 ? last_estimated_size : 0;
     ByteString decoder = DecoderArray[i].first;
     const CPDF_Dictionary* pParam = ToDictionary(DecoderArray[i].second);
-    uint8_t* new_buf = nullptr;
+    std::unique_ptr<uint8_t, FxFreeDeleter> new_buf;
     uint32_t new_size = 0xFFFFFFFF;
     uint32_t offset = FX_INVALID_OFFSET;
     if (decoder == "Crypt")
@@ -404,39 +404,29 @@
     if (decoder == "FlateDecode" || decoder == "Fl") {
       if (bImageAcc && i == nSize - 1) {
         *ImageEncoding = "FlateDecode";
-        *dest_buf = last_span.data();
+        *dest_buf = std::move(result);
         *dest_size = last_span.size();
         *pImageParams = pParam;
         return true;
       }
-      std::unique_ptr<uint8_t, FxFreeDeleter> result;
       offset = FlateOrLZWDecode(false, last_span, pParam, estimated_size,
-                                &result, &new_size);
-      new_buf = result.release();
+                                &new_buf, &new_size);
     } else if (decoder == "LZWDecode" || decoder == "LZW") {
-      std::unique_ptr<uint8_t, FxFreeDeleter> result;
       offset = FlateOrLZWDecode(true, last_span, pParam, estimated_size,
-                                &result, &new_size);
-      new_buf = result.release();
+                                &new_buf, &new_size);
     } else if (decoder == "ASCII85Decode" || decoder == "A85") {
-      std::unique_ptr<uint8_t, FxFreeDeleter> result;
-      offset = A85Decode(last_span, &result, &new_size);
-      new_buf = result.release();
+      offset = A85Decode(last_span, &new_buf, &new_size);
     } else if (decoder == "ASCIIHexDecode" || decoder == "AHx") {
-      std::unique_ptr<uint8_t, FxFreeDeleter> result;
-      offset = HexDecode(last_span, &result, &new_size);
-      new_buf = result.release();
+      offset = HexDecode(last_span, &new_buf, &new_size);
     } else if (decoder == "RunLengthDecode" || decoder == "RL") {
       if (bImageAcc && i == nSize - 1) {
         *ImageEncoding = "RunLengthDecode";
-        *dest_buf = last_span.data();
+        *dest_buf = std::move(result);
         *dest_size = last_span.size();
         *pImageParams = pParam;
         return true;
       }
-      std::unique_ptr<uint8_t, FxFreeDeleter> result;
-      offset = RunLengthDecode(last_span, &result, &new_size);
-      new_buf = result.release();
+      offset = RunLengthDecode(last_span, &new_buf, &new_size);
     } else {
       // If we get here, assume it's an image decoder.
       if (decoder == "DCT")
@@ -445,24 +435,19 @@
         decoder = "CCITTFaxDecode";
       *ImageEncoding = std::move(decoder);
       *pImageParams = pParam;
-      *dest_buf = last_span.data();
+      *dest_buf = std::move(result);
       *dest_size = last_span.size();
       return true;
     }
-    if (last_span.data() != src_span.data()) {
-      auto* temp = last_span.data();
-      last_span = {};  // Spans can't outlive their data.
-      FX_Free(temp);
-    }
-    if (offset == FX_INVALID_OFFSET) {
-      FX_Free(new_buf);
+    if (offset == FX_INVALID_OFFSET)
       return false;
-    }
-    last_span = {new_buf, new_size};
+
+    last_span = {new_buf.get(), new_size};
+    result = std::move(new_buf);
   }
   ImageEncoding->clear();
   *pImageParams = nullptr;
-  *dest_buf = last_span.data();
+  *dest_buf = std::move(result);
   *dest_size = last_span.size();
   return true;
 }
diff --git a/core/fpdfapi/parser/fpdf_parser_decode.h b/core/fpdfapi/parser/fpdf_parser_decode.h
index 57ee271..2b7832f 100644
--- a/core/fpdfapi/parser/fpdf_parser_decode.h
+++ b/core/fpdfapi/parser/fpdf_parser_decode.h
@@ -73,7 +73,7 @@
                     const CPDF_Dictionary* pDict,
                     uint32_t estimated_size,
                     bool bImageAcc,
-                    uint8_t** dest_buf,
+                    std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
                     uint32_t* dest_size,
                     ByteString* ImageEncoding,
                     UnownedPtr<const CPDF_Dictionary>* pImageParms);