From 90555e06b0c03777bca17ca423b765b3cb517f56 Mon Sep 17 00:00:00 2001 From: Artem Strygin Date: Fri, 28 Jul 2017 19:41:59 +0300 Subject: Add CPDF_Stream::ReplaceData method. Change-Id: I94b2e8f6fd522b97c917037e32fb3bcbeea0cbeb Reviewed-on: https://pdfium-review.googlesource.com/8911 Commit-Queue: Lei Zhang Reviewed-by: Lei Zhang --- core/fpdfapi/parser/cpdf_object_unittest.cpp | 45 ++++++++++++++++++++++++++++ core/fpdfapi/parser/cpdf_stream.cpp | 13 ++++++-- core/fpdfapi/parser/cpdf_stream.h | 4 +++ 3 files changed, 60 insertions(+), 2 deletions(-) (limited to 'core/fpdfapi/parser') diff --git a/core/fpdfapi/parser/cpdf_object_unittest.cpp b/core/fpdfapi/parser/cpdf_object_unittest.cpp index 7d474b2e7d..ffaa2648a3 100644 --- a/core/fpdfapi/parser/cpdf_object_unittest.cpp +++ b/core/fpdfapi/parser/cpdf_object_unittest.cpp @@ -785,6 +785,51 @@ TEST(PDFArrayTest, ConvertIndirect) { EXPECT_EQ(42, array->GetIntegerAt(0)); } +TEST(PDFStreamTest, SetData) { + std::vector data(100); + auto stream = pdfium::MakeUnique(); + stream->InitStream(data.data(), data.size(), + pdfium::MakeUnique()); + EXPECT_EQ(static_cast(data.size()), + stream->GetDict()->GetIntegerFor("Length")); + + stream->GetDict()->SetNewFor("Filter", L"SomeFilter"); + stream->GetDict()->SetNewFor("DecodeParms", L"SomeParams"); + + std::vector new_data(data.size() * 2); + stream->SetData(new_data.data(), new_data.size()); + + // The "Length" field should be updated for new data size. + EXPECT_EQ(static_cast(new_data.size()), + stream->GetDict()->GetIntegerFor("Length")); + + // The "Filter" and "DecodeParms" fields should not be changed. + EXPECT_EQ(stream->GetDict()->GetUnicodeTextFor("Filter"), L"SomeFilter"); + EXPECT_EQ(stream->GetDict()->GetUnicodeTextFor("DecodeParms"), L"SomeParams"); +} + +TEST(PDFStreamTest, SetDataAndRemoveFilter) { + std::vector data(100); + auto stream = pdfium::MakeUnique(); + stream->InitStream(data.data(), data.size(), + pdfium::MakeUnique()); + EXPECT_EQ(static_cast(data.size()), + stream->GetDict()->GetIntegerFor("Length")); + + stream->GetDict()->SetNewFor("Filter", L"SomeFilter"); + stream->GetDict()->SetNewFor("DecodeParms", L"SomeParams"); + + std::vector new_data(data.size() * 2); + stream->SetDataAndRemoveFilter(new_data.data(), new_data.size()); + // The "Length" field should be updated for new data size. + EXPECT_EQ(static_cast(new_data.size()), + stream->GetDict()->GetIntegerFor("Length")); + + // The "Filter" and "DecodeParms" should be removed. + EXPECT_FALSE(stream->GetDict()->KeyExist("Filter")); + EXPECT_FALSE(stream->GetDict()->KeyExist("DecodeParms")); +} + TEST(PDFDictionaryTest, CloneDirectObject) { CPDF_IndirectObjectHolder objects_holder; auto dict = pdfium::MakeUnique(); diff --git a/core/fpdfapi/parser/cpdf_stream.cpp b/core/fpdfapi/parser/cpdf_stream.cpp index ec12ac5080..d430a4fb45 100644 --- a/core/fpdfapi/parser/cpdf_stream.cpp +++ b/core/fpdfapi/parser/cpdf_stream.cpp @@ -97,6 +97,17 @@ std::unique_ptr CPDF_Stream::CloneNonCyclic( std::move(pNewDict)); } +void CPDF_Stream::SetDataAndRemoveFilter(const uint8_t* pData, uint32_t size) { + SetData(pData, size); + m_pDict->RemoveFor("Filter"); + m_pDict->RemoveFor("DecodeParms"); +} + +void CPDF_Stream::SetDataAndRemoveFilter(std::ostringstream* stream) { + SetDataAndRemoveFilter( + reinterpret_cast(stream->str().c_str()), stream->tellp()); +} + void CPDF_Stream::SetData(const uint8_t* pData, uint32_t size) { m_bMemoryBased = true; m_pDataBuf.reset(FX_Alloc(uint8_t, size)); @@ -106,8 +117,6 @@ void CPDF_Stream::SetData(const uint8_t* pData, uint32_t size) { if (!m_pDict) m_pDict = pdfium::MakeUnique(); m_pDict->SetNewFor("Length", static_cast(size)); - m_pDict->RemoveFor("Filter"); - m_pDict->RemoveFor("DecodeParms"); } void CPDF_Stream::SetData(std::ostringstream* stream) { diff --git a/core/fpdfapi/parser/cpdf_stream.h b/core/fpdfapi/parser/cpdf_stream.h index d58f608f72..2795f7daae 100644 --- a/core/fpdfapi/parser/cpdf_stream.h +++ b/core/fpdfapi/parser/cpdf_stream.h @@ -42,6 +42,10 @@ class CPDF_Stream : public CPDF_Object { // Does not takes ownership of |pData|, copies into internally-owned buffer. void SetData(const uint8_t* pData, uint32_t size); void SetData(std::ostringstream* stream); + // Set data and remove "Filter" and "DecodeParms" fields from stream + // dictionary. + void SetDataAndRemoveFilter(const uint8_t* pData, uint32_t size); + void SetDataAndRemoveFilter(std::ostringstream* stream); void InitStream(const uint8_t* pData, uint32_t size, -- cgit v1.2.3