diff options
author | Artem Strygin <art-snake@yandex-team.ru> | 2017-07-28 19:41:59 +0300 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2017-07-28 18:22:46 +0000 |
commit | 90555e06b0c03777bca17ca423b765b3cb517f56 (patch) | |
tree | 8223800b230be79d0af7dc04454e85a2fcee7713 | |
parent | e7a99de4f711302d57fe22682a9a8c3cfddb458c (diff) | |
download | pdfium-90555e06b0c03777bca17ca423b765b3cb517f56.tar.xz |
Add CPDF_Stream::ReplaceData method.chromium/3170
Change-Id: I94b2e8f6fd522b97c917037e32fb3bcbeea0cbeb
Reviewed-on: https://pdfium-review.googlesource.com/8911
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
-rw-r--r-- | core/fpdfapi/parser/cpdf_object_unittest.cpp | 45 | ||||
-rw-r--r-- | core/fpdfapi/parser/cpdf_stream.cpp | 13 | ||||
-rw-r--r-- | core/fpdfapi/parser/cpdf_stream.h | 4 | ||||
-rw-r--r-- | core/fpdfdoc/cpvt_generateap.cpp | 2 | ||||
-rw-r--r-- | fpdfsdk/fpdf_flatten.cpp | 5 | ||||
-rw-r--r-- | fpdfsdk/fpdfannot.cpp | 2 | ||||
-rw-r--r-- | fpdfsdk/pwl/cpwl_appstream.cpp | 3 |
7 files changed, 67 insertions, 7 deletions
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<uint8_t> data(100); + auto stream = pdfium::MakeUnique<CPDF_Stream>(); + stream->InitStream(data.data(), data.size(), + pdfium::MakeUnique<CPDF_Dictionary>()); + EXPECT_EQ(static_cast<int>(data.size()), + stream->GetDict()->GetIntegerFor("Length")); + + stream->GetDict()->SetNewFor<CPDF_String>("Filter", L"SomeFilter"); + stream->GetDict()->SetNewFor<CPDF_String>("DecodeParms", L"SomeParams"); + + std::vector<uint8_t> 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<int>(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<uint8_t> data(100); + auto stream = pdfium::MakeUnique<CPDF_Stream>(); + stream->InitStream(data.data(), data.size(), + pdfium::MakeUnique<CPDF_Dictionary>()); + EXPECT_EQ(static_cast<int>(data.size()), + stream->GetDict()->GetIntegerFor("Length")); + + stream->GetDict()->SetNewFor<CPDF_String>("Filter", L"SomeFilter"); + stream->GetDict()->SetNewFor<CPDF_String>("DecodeParms", L"SomeParams"); + + std::vector<uint8_t> 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<int>(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<CPDF_Dictionary>(); 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_Object> 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<const uint8_t*>(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<CPDF_Dictionary>(); m_pDict->SetNewFor<CPDF_Number>("Length", static_cast<int>(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, diff --git a/core/fpdfdoc/cpvt_generateap.cpp b/core/fpdfdoc/cpvt_generateap.cpp index 956f91289b..d1abde681d 100644 --- a/core/fpdfdoc/cpvt_generateap.cpp +++ b/core/fpdfdoc/cpvt_generateap.cpp @@ -429,7 +429,7 @@ bool GenerateWidgetAP(CPDF_Document* pDoc, } break; } if (pNormalStream) { - pNormalStream->SetData(&sAppStream); + pNormalStream->SetDataAndRemoveFilter(&sAppStream); pStreamDict = pNormalStream->GetDict(); if (pStreamDict) { pStreamDict->SetMatrixFor("Matrix", matrix); diff --git a/fpdfsdk/fpdf_flatten.cpp b/fpdfsdk/fpdf_flatten.cpp index e530553f5a..16528c2ee3 100644 --- a/fpdfsdk/fpdf_flatten.cpp +++ b/fpdfsdk/fpdf_flatten.cpp @@ -203,7 +203,8 @@ void SetPageContents(const CFX_ByteString& key, CFX_ByteString sBody = CFX_ByteString((const char*)pAcc->GetData(), pAcc->GetSize()); sStream = sStream + sBody + "\nQ"; - pContentsStream->SetData(sStream.raw_str(), sStream.GetLength()); + pContentsStream->SetDataAndRemoveFilter(sStream.raw_str(), + sStream.GetLength()); pContentsArray->AddNew<CPDF_Reference>(pDocument, pContentsStream->GetObjNum()); pPage->SetNewFor<CPDF_Reference>("Contents", pDocument, @@ -405,7 +406,7 @@ DLLEXPORT int STDCALL FPDFPage_Flatten(FPDF_PAGE page, int nFlag) { sTemp.Format("q %f 0 0 %f %f %f cm /%s Do Q\n", m.a, m.d, m.e, m.f, sFormName.c_str()); sStream += sTemp; - pNewXObject->SetData(sStream.raw_str(), sStream.GetLength()); + pNewXObject->SetDataAndRemoveFilter(sStream.raw_str(), sStream.GetLength()); } pPageDict->RemoveFor("Annots"); return FLATTEN_SUCCESS; diff --git a/fpdfsdk/fpdfannot.cpp b/fpdfsdk/fpdfannot.cpp index fcbed5c2ce..64c95a3777 100644 --- a/fpdfsdk/fpdfannot.cpp +++ b/fpdfsdk/fpdfannot.cpp @@ -179,7 +179,7 @@ void UpdateContentStream(CPDF_Form* pForm, CPDF_Stream* pStream) { CPDF_PageContentGenerator generator(pForm); std::ostringstream buf; generator.ProcessPageObjects(&buf); - pStream->SetData(&buf); + pStream->SetDataAndRemoveFilter(&buf); } } // namespace diff --git a/fpdfsdk/pwl/cpwl_appstream.cpp b/fpdfsdk/pwl/cpwl_appstream.cpp index fe401639da..405a205507 100644 --- a/fpdfsdk/pwl/cpwl_appstream.cpp +++ b/fpdfsdk/pwl/cpwl_appstream.cpp @@ -1943,7 +1943,8 @@ void CPWL_AppStream::Write(const CFX_ByteString& sAPType, } pStreamDict->SetMatrixFor("Matrix", widget_->GetMatrix()); pStreamDict->SetRectFor("BBox", widget_->GetRotatedRect()); - pStream->SetData((uint8_t*)(sContents.c_str()), sContents.GetLength()); + pStream->SetDataAndRemoveFilter((uint8_t*)(sContents.c_str()), + sContents.GetLength()); } void CPWL_AppStream::Remove(const CFX_ByteString& sAPType) { |