From eababa10789bc0d73a325291e2854090ee3896cd Mon Sep 17 00:00:00 2001 From: Artem Strygin Date: Wed, 6 Jun 2018 12:31:18 +0000 Subject: Use CPDF_StreamAcc to data access of CPDF_Stream. Change-Id: I68b88e013ac542f245dbe7b6889799c814d46eb8 Reviewed-on: https://pdfium-review.googlesource.com/33690 Commit-Queue: Art Snake Reviewed-by: Lei Zhang --- core/fpdfapi/parser/cpdf_object_unittest.cpp | 19 ++++++------ core/fpdfapi/parser/cpdf_stream.h | 4 ++- core/fpdfapi/parser/cpdf_stream_acc.cpp | 10 +++---- fpdfsdk/cpdfsdk_helpers.cpp | 43 ++++++---------------------- fpdfsdk/fpdf_edit_embeddertest.cpp | 13 ++++++--- fpdfsdk/fpdf_editimg.cpp | 11 +++++-- 6 files changed, 45 insertions(+), 55 deletions(-) diff --git a/core/fpdfapi/parser/cpdf_object_unittest.cpp b/core/fpdfapi/parser/cpdf_object_unittest.cpp index 4780e87bc0..856dd0ac3b 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 @@ class PDFObjectsTest : public testing::Test { // Compare dictionaries. if (!Equal(stream1->GetDict(), stream2->GetDict())) return false; + + auto streamAcc1 = pdfium::MakeRetain(stream1); + streamAcc1->LoadAllDataRaw(); + auto streamAcc2 = pdfium::MakeRetain(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 cc3dcac227..7e98f300ba 100644 --- a/core/fpdfapi/parser/cpdf_stream.h +++ b/core/fpdfapi/parser/cpdf_stream.h @@ -37,7 +37,9 @@ class CPDF_Stream : public CPDF_Object { 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 9cf9a1f464..1734b0ddcb 100644 --- a/core/fpdfapi/parser/cpdf_stream_acc.cpp +++ b/core/fpdfapi/parser/cpdf_stream_acc.cpp @@ -26,7 +26,7 @@ void CPDF_StreamAcc::LoadAllData(bool bRawAccess, 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 @@ void CPDF_StreamAcc::LoadAllData(bool bRawAccess, 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 @@ void CPDF_StreamAcc::LoadAllData(bool bRawAccess, 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 @@ const CPDF_Dictionary* CPDF_StreamAcc::GetDict() const { 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 e96b09f3a1..1ceecfe21f 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 @@ unsigned long DecodeStreamMaybeCopyAndReturnLength(const CPDF_Stream* stream, 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); - - // 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; + auto stream_acc = pdfium::MakeRetain(stream); + stream_acc->LoadAllDataFiltered(); + const auto stream_data_size = stream_acc->GetSize(); + if (!buffer || buflen < stream_data_size) + return stream_data_size; + + 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 b2a7c32153..f339a82336 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 @@ class FPDFEditEmbeddertest : public EmbedderTest { EXPECT_TRUE(font_desc->KeyExist(present)); EXPECT_FALSE(font_desc->KeyExist(absent)); + auto streamAcc = + pdfium::MakeRetain(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(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 fed1581e2d..7aa93e98ec 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 @@ FPDFImageObj_GetImageDataRaw(FPDF_PAGEOBJECT image_object, if (!pImgStream) return 0; - uint32_t len = pImgStream->GetRawSize(); - if (buffer && buflen >= len) - memcpy(buffer, pImgStream->GetRawData(), len); + auto streamAcc = pdfium::MakeRetain(pImgStream); + streamAcc->LoadAllDataRaw(); + const uint32_t len = streamAcc->GetSize(); + if (!buffer || buflen < len) + return len; + + memcpy(buffer, streamAcc->GetData(), len); return len; } -- cgit v1.2.3