Use CPDF_StreamAcc to data access of CPDF_Stream.

Change-Id: I68b88e013ac542f245dbe7b6889799c814d46eb8
Reviewed-on: https://pdfium-review.googlesource.com/33690
Commit-Queue: Art Snake <art-snake@yandex-team.ru>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/parser/cpdf_object_unittest.cpp b/core/fpdfapi/parser/cpdf_object_unittest.cpp
index 4780e87..856dd0a 100644
--- a/core/fpdfapi/parser/cpdf_object_unittest.cpp
+++ b/core/fpdfapi/parser/cpdf_object_unittest.cpp
@@ -17,6 +17,7 @@
 #include "core/fpdfapi/parser/cpdf_number.h"
 #include "core/fpdfapi/parser/cpdf_reference.h"
 #include "core/fpdfapi/parser/cpdf_stream.h"
+#include "core/fpdfapi/parser/cpdf_stream_acc.h"
 #include "core/fpdfapi/parser/cpdf_string.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -153,16 +154,18 @@
         // Compare dictionaries.
         if (!Equal(stream1->GetDict(), stream2->GetDict()))
           return false;
+
+        auto streamAcc1 = pdfium::MakeRetain<CPDF_StreamAcc>(stream1);
+        streamAcc1->LoadAllDataRaw();
+        auto streamAcc2 = pdfium::MakeRetain<CPDF_StreamAcc>(stream2);
+        streamAcc2->LoadAllDataRaw();
+
         // Compare sizes.
-        if (stream1->GetRawSize() != stream2->GetRawSize())
+        if (streamAcc1->GetSize() != streamAcc2->GetSize())
           return false;
-        // Compare contents.
-        // Since this function is used for testing Clone(), only memory based
-        // streams need to be handled.
-        if (!stream1->IsMemoryBased() || !stream2->IsMemoryBased())
-          return false;
-        return memcmp(stream1->GetRawData(), stream2->GetRawData(),
-                      stream1->GetRawSize()) == 0;
+
+        return memcmp(streamAcc1->GetData(), streamAcc2->GetData(),
+                      streamAcc2->GetSize()) == 0;
       }
       case CPDF_Object::REFERENCE:
         return obj1->AsReference()->GetRefObjNum() ==
diff --git a/core/fpdfapi/parser/cpdf_stream.h b/core/fpdfapi/parser/cpdf_stream.h
index cc3dcac..7e98f30 100644
--- a/core/fpdfapi/parser/cpdf_stream.h
+++ b/core/fpdfapi/parser/cpdf_stream.h
@@ -37,7 +37,9 @@
   bool WriteTo(IFX_ArchiveStream* archive) const override;
 
   uint32_t GetRawSize() const { return m_dwSize; }
-  uint8_t* GetRawData() const { return m_pDataBuf.get(); }
+  // Will be null in case when stream is not memory based.
+  // Use CPDF_StreamAcc to data access in all cases.
+  uint8_t* GetInMemoryRawData() const { return m_pDataBuf.get(); }
 
   // Does not takes ownership of |pData|, copies into internally-owned buffer.
   void SetData(const uint8_t* pData, uint32_t size);
diff --git a/core/fpdfapi/parser/cpdf_stream_acc.cpp b/core/fpdfapi/parser/cpdf_stream_acc.cpp
index 9cf9a1f..1734b0d 100644
--- a/core/fpdfapi/parser/cpdf_stream_acc.cpp
+++ b/core/fpdfapi/parser/cpdf_stream_acc.cpp
@@ -26,7 +26,7 @@
   bool bProcessRawData = bRawAccess || !m_pStream->HasFilter();
   if (bProcessRawData && m_pStream->IsMemoryBased()) {
     m_dwSize = m_pStream->GetRawSize();
-    m_pData = m_pStream->GetRawData();
+    m_pData = m_pStream->GetInMemoryRawData();
     return;
   }
   uint32_t dwSrcSize = m_pStream->GetRawSize();
@@ -35,7 +35,7 @@
 
   uint8_t* pSrcData;
   if (m_pStream->IsMemoryBased()) {
-    pSrcData = m_pStream->GetRawData();
+    pSrcData = m_pStream->GetInMemoryRawData();
   } else {
     pSrcData = m_pSrcData = FX_Alloc(uint8_t, dwSrcSize);
     if (!m_pStream->ReadRawData(0, pSrcData, dwSrcSize))
@@ -50,10 +50,10 @@
     m_pData = pSrcData;
     m_dwSize = dwSrcSize;
   }
-  if (pSrcData != m_pStream->GetRawData() && pSrcData != m_pData)
+  if (pSrcData != m_pStream->GetInMemoryRawData() && pSrcData != m_pData)
     FX_Free(pSrcData);
   m_pSrcData = nullptr;
-  m_bNewBuf = m_pData != m_pStream->GetRawData();
+  m_bNewBuf = m_pData != m_pStream->GetInMemoryRawData();
 }
 
 void CPDF_StreamAcc::LoadAllDataFiltered() {
@@ -71,7 +71,7 @@
 uint8_t* CPDF_StreamAcc::GetData() const {
   if (m_bNewBuf)
     return m_pData;
-  return m_pStream ? m_pStream->GetRawData() : nullptr;
+  return m_pStream ? m_pStream->GetInMemoryRawData() : nullptr;
 }
 
 uint32_t CPDF_StreamAcc::GetSize() const {
diff --git a/fpdfsdk/cpdfsdk_helpers.cpp b/fpdfsdk/cpdfsdk_helpers.cpp
index e96b09f..1ceecfe 100644
--- a/fpdfsdk/cpdfsdk_helpers.cpp
+++ b/fpdfsdk/cpdfsdk_helpers.cpp
@@ -11,6 +11,7 @@
 #include "core/fpdfapi/page/cpdf_page.h"
 #include "core/fpdfapi/parser/cpdf_array.h"
 #include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfapi/parser/cpdf_stream_acc.h"
 #include "core/fpdfapi/parser/fpdf_parser_decode.h"
 #include "core/fpdfdoc/cpdf_annot.h"
 #include "core/fpdfdoc/cpdf_interform.h"
@@ -319,40 +320,14 @@
                                                    void* buffer,
                                                    unsigned long buflen) {
   ASSERT(stream);
-  uint8_t* data = stream->GetRawData();
-  uint32_t len = stream->GetRawSize();
-  const CPDF_Dictionary* dict = stream->GetDict();
-  const CPDF_Object* decoder =
-      dict ? dict->GetDirectObjectFor("Filter") : nullptr;
-  if (decoder && (decoder->IsArray() || decoder->IsName())) {
-    // Decode the stream if one or more stream filters are specified.
-    uint8_t* decoded_data = nullptr;
-    uint32_t decoded_len = 0;
-    ByteString dummy_last_decoder;
-    const CPDF_Dictionary* dummy_last_param;
-    if (PDF_DataDecode(data, len, dict,
-                       dict->GetIntegerFor(pdfium::stream::kDL), false,
-                       &decoded_data, &decoded_len, &dummy_last_decoder,
-                       &dummy_last_param)) {
-      if (buffer && buflen >= decoded_len)
-        memcpy(buffer, decoded_data, decoded_len);
+  auto stream_acc = pdfium::MakeRetain<CPDF_StreamAcc>(stream);
+  stream_acc->LoadAllDataFiltered();
+  const auto stream_data_size = stream_acc->GetSize();
+  if (!buffer || buflen < stream_data_size)
+    return stream_data_size;
 
-      // Free the buffer for the decoded data if it was allocated by
-      // PDF_DataDecode(). Note that for images with a single image-specific
-      // filter, |decoded_data| is directly assigned to be |data|, so
-      // |decoded_data| does not need to be freed.
-      if (decoded_data != data)
-        FX_Free(decoded_data);
-
-      return decoded_len;
-    }
-  }
-  // Copy the raw data and return its length if there is no valid filter
-  // specified or if decoding failed.
-  if (buffer && buflen >= len)
-    memcpy(buffer, data, len);
-
-  return len;
+  memcpy(buffer, stream_acc->GetData(), stream_data_size);
+  return stream_data_size;
 }
 
 unsigned long Utf16EncodeMaybeCopyAndReturnLength(const WideString& text,
diff --git a/fpdfsdk/fpdf_edit_embeddertest.cpp b/fpdfsdk/fpdf_edit_embeddertest.cpp
index b2a7c32..f339a82 100644
--- a/fpdfsdk/fpdf_edit_embeddertest.cpp
+++ b/fpdfsdk/fpdf_edit_embeddertest.cpp
@@ -13,6 +13,7 @@
 #include "core/fpdfapi/parser/cpdf_dictionary.h"
 #include "core/fpdfapi/parser/cpdf_number.h"
 #include "core/fpdfapi/parser/cpdf_stream.h"
+#include "core/fpdfapi/parser/cpdf_stream_acc.h"
 #include "core/fxcrt/fx_system.h"
 #include "fpdfsdk/cpdfsdk_helpers.h"
 #include "public/cpp/fpdf_scopers.h"
@@ -74,14 +75,18 @@
     EXPECT_TRUE(font_desc->KeyExist(present));
     EXPECT_FALSE(font_desc->KeyExist(absent));
 
+    auto streamAcc =
+        pdfium::MakeRetain<CPDF_StreamAcc>(font_desc->GetStreamFor(present));
+    streamAcc->LoadAllDataRaw();
+
     // Check that the font stream is the one that was provided
-    const CPDF_Stream* font_stream = font_desc->GetStreamFor(present);
-    ASSERT_EQ(size, font_stream->GetRawSize());
+    ASSERT_EQ(size, streamAcc->GetSize());
     if (font_type == FPDF_FONT_TRUETYPE) {
       ASSERT_EQ(static_cast<int>(size),
-                font_stream->GetDict()->GetIntegerFor("Length1"));
+                streamAcc->GetDict()->GetIntegerFor("Length1"));
     }
-    uint8_t* stream_data = font_stream->GetRawData();
+
+    const uint8_t* stream_data = streamAcc->GetData();
     for (size_t j = 0; j < size; j++)
       EXPECT_EQ(data[j], stream_data[j]) << " at byte " << j;
   }
diff --git a/fpdfsdk/fpdf_editimg.cpp b/fpdfsdk/fpdf_editimg.cpp
index fed1581..7aa93e9 100644
--- a/fpdfsdk/fpdf_editimg.cpp
+++ b/fpdfsdk/fpdf_editimg.cpp
@@ -13,6 +13,7 @@
 #include "core/fpdfapi/page/cpdf_pageobject.h"
 #include "core/fpdfapi/parser/cpdf_array.h"
 #include "core/fpdfapi/parser/cpdf_name.h"
+#include "core/fpdfapi/parser/cpdf_stream_acc.h"
 #include "core/fpdfapi/render/cpdf_dibsource.h"
 #include "fpdfsdk/cpdfsdk_customaccess.h"
 #include "fpdfsdk/cpdfsdk_helpers.h"
@@ -221,10 +222,14 @@
   if (!pImgStream)
     return 0;
 
-  uint32_t len = pImgStream->GetRawSize();
-  if (buffer && buflen >= len)
-    memcpy(buffer, pImgStream->GetRawData(), len);
+  auto streamAcc = pdfium::MakeRetain<CPDF_StreamAcc>(pImgStream);
+  streamAcc->LoadAllDataRaw();
 
+  const uint32_t len = streamAcc->GetSize();
+  if (!buffer || buflen < len)
+    return len;
+
+  memcpy(buffer, streamAcc->GetData(), len);
   return len;
 }