diff options
-rw-r--r-- | fpdfsdk/fpdf_flatten.cpp | 47 | ||||
-rw-r--r-- | fpdfsdk/fpdf_flatten_embeddertest.cpp | 17 | ||||
-rw-r--r-- | testing/resources/bug_890322.in | 1 | ||||
-rw-r--r-- | testing/resources/bug_890322.pdf | 5 | ||||
-rw-r--r-- | testing/resources/bug_896366.in | 60 | ||||
-rw-r--r-- | testing/resources/bug_896366.pdf | 73 |
6 files changed, 182 insertions, 21 deletions
diff --git a/fpdfsdk/fpdf_flatten.cpp b/fpdfsdk/fpdf_flatten.cpp index 98529c53c8..0cee611144 100644 --- a/fpdfsdk/fpdf_flatten.cpp +++ b/fpdfsdk/fpdf_flatten.cpp @@ -167,52 +167,61 @@ CFX_FloatRect CalculateRect(std::vector<CFX_FloatRect>* pRectArray) { return rcRet; } -CPDF_Object* NewIndirectContentsStream(const ByteString& key, - CPDF_Document* pDocument) { +ByteString GenerateFlattenedContent(const ByteString& key) { + return "q 1 0 0 1 0 0 cm /" + key + " Do Q"; +} + +CPDF_Object* NewIndirectContentsStream(CPDF_Document* pDocument, + const ByteString& contents) { CPDF_Stream* pNewContents = pDocument->NewIndirect<CPDF_Stream>( nullptr, 0, pdfium::MakeUnique<CPDF_Dictionary>(pDocument->GetByteStringPool())); - ByteString sStream = - ByteString::Format("q 1 0 0 1 0 0 cm /%s Do Q", key.c_str()); - pNewContents->SetData(sStream.AsRawSpan()); + pNewContents->SetData(contents.AsRawSpan()); return pNewContents; } void SetPageContents(const ByteString& key, CPDF_Dictionary* pPage, CPDF_Document* pDocument) { - CPDF_Array* pContentsArray = nullptr; + CPDF_Array* pContentsArray = + pPage->GetArrayFor(pdfium::page_object::kContents); CPDF_Stream* pContentsStream = pPage->GetStreamFor(pdfium::page_object::kContents); - if (!pContentsStream) { - pContentsArray = pPage->GetArrayFor(pdfium::page_object::kContents); - if (!pContentsArray) { - if (!key.IsEmpty()) { - pPage->SetFor(pdfium::page_object::kContents, - NewIndirectContentsStream(key, pDocument) - ->MakeReference(pDocument)); - } - return; + if (!pContentsStream && !pContentsArray) { + if (!key.IsEmpty()) { + pPage->SetFor( + pdfium::page_object::kContents, + NewIndirectContentsStream(pDocument, GenerateFlattenedContent(key)) + ->MakeReference(pDocument)); } + return; } + pPage->ConvertToIndirectObjectFor(pdfium::page_object::kContents, pDocument); - if (!pContentsArray) { - pContentsArray = pDocument->NewIndirect<CPDF_Array>(); + if (pContentsArray) { + pContentsArray->InsertAt( + 0, NewIndirectContentsStream(pDocument, "q")->MakeReference(pDocument)); + pContentsArray->Add( + NewIndirectContentsStream(pDocument, "Q")->MakeReference(pDocument)); + } else { ByteString sStream = "q\n"; { auto pAcc = pdfium::MakeRetain<CPDF_StreamAcc>(pContentsStream); pAcc->LoadAllDataFiltered(); - sStream += ByteString(pAcc->GetData(), pAcc->GetSize()); + sStream += ByteString(pAcc->GetSpan()); sStream += "\nQ"; } pContentsStream->SetDataAndRemoveFilter(sStream.AsRawSpan()); + + pContentsArray = pDocument->NewIndirect<CPDF_Array>(); pContentsArray->Add(pContentsStream->MakeReference(pDocument)); pPage->SetFor(pdfium::page_object::kContents, pContentsArray->MakeReference(pDocument)); } if (!key.IsEmpty()) { pContentsArray->Add( - NewIndirectContentsStream(key, pDocument)->MakeReference(pDocument)); + NewIndirectContentsStream(pDocument, GenerateFlattenedContent(key)) + ->MakeReference(pDocument)); } } diff --git a/fpdfsdk/fpdf_flatten_embeddertest.cpp b/fpdfsdk/fpdf_flatten_embeddertest.cpp index c861d75711..450c30c730 100644 --- a/fpdfsdk/fpdf_flatten_embeddertest.cpp +++ b/fpdfsdk/fpdf_flatten_embeddertest.cpp @@ -54,3 +54,20 @@ TEST_F(FPDFFlattenEmbeddertest, BUG_890322) { VerifySavedDocument(200, 200, md5_hash); } + +TEST_F(FPDFFlattenEmbeddertest, BUG_896366) { + static const char md5_hash[] = "f71ab085c52c8445ae785eca3ec858b1"; + EXPECT_TRUE(OpenDocument("bug_896366.pdf")); + FPDF_PAGE page = LoadPage(0); + ASSERT_TRUE(page); + + ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT); + CompareBitmap(bitmap.get(), 612, 792, md5_hash); + + EXPECT_EQ(FLATTEN_SUCCESS, FPDFPage_Flatten(page, FLAT_PRINT)); + EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0)); + + UnloadPage(page); + + VerifySavedDocument(612, 792, md5_hash); +} diff --git a/testing/resources/bug_890322.in b/testing/resources/bug_890322.in index ea55ac652f..0c68775657 100644 --- a/testing/resources/bug_890322.in +++ b/testing/resources/bug_890322.in @@ -42,6 +42,7 @@ q 0 0 50 40 re B* Q endstream +endobj {{object 6 0}} << {{streamlen}} >> diff --git a/testing/resources/bug_890322.pdf b/testing/resources/bug_890322.pdf index 2183aafeef..2900c1bedc 100644 --- a/testing/resources/bug_890322.pdf +++ b/testing/resources/bug_890322.pdf @@ -43,6 +43,7 @@ q 0 0 50 40 re B* Q endstream +endobj 6 0 obj << /Length 4 >> @@ -59,11 +60,11 @@ xref 0000000165 00000 n 0000000282 00000 n 0000000474 00000 n -0000000587 00000 n +0000000594 00000 n trailer << /Root 1 0 R /Size 7 >> startxref -641 +648 %%EOF diff --git a/testing/resources/bug_896366.in b/testing/resources/bug_896366.in new file mode 100644 index 0000000000..86bd6fee32 --- /dev/null +++ b/testing/resources/bug_896366.in @@ -0,0 +1,60 @@ +{{header}} +{{object 1 0}} << + /Type /Catalog + /Pages 2 0 R + /AcroForm << + /Fields [4 0 R] + >> +>> +endobj +{{object 2 0}} << + /Type /Pages + /Kids [3 0 R] + /Count 1 +>> +endobj +{{object 3 0}} << + /Type /Page + /Parent 2 0 R + /Annots [4 0 R] + /Contents [6 0 R] + /MediaBox [0 0 612 792] +>> +endobj +{{object 4 0}} << + /Type /Annot + /Subtype /Widget + /F 4 + /FT /Btn + /Rect [ 75 80 125 120 ] + /T (PushButton) + /Ff 65536 + /H + /P + /AP << /N 5 0 R >> + /MK << /BG [ 1.0 0.0 0.0 ] >> +>> +endobj +{{object 5 0}} << + /Subtype /Form + /BBox [ 0 40 50 00 ] + {{streamlen}} +>> +stream +q +0 0 1 rg +0 0 50 40 re B* +Q +endstream +endobj +{{object 6 0}} << + {{streamlen}} +>> +stream +1 0 0 -1 0 792 cm +endstream +endobj +{{xref}} +{{trailer}} +{{startxref}} +%%EOF diff --git a/testing/resources/bug_896366.pdf b/testing/resources/bug_896366.pdf new file mode 100644 index 0000000000..0310fb95c4 --- /dev/null +++ b/testing/resources/bug_896366.pdf @@ -0,0 +1,73 @@ +%PDF-1.7 +% ò¤ô +1 0 obj << + /Type /Catalog + /Pages 2 0 R + /AcroForm << + /Fields [4 0 R] + >> +>> +endobj +2 0 obj << + /Type /Pages + /Kids [3 0 R] + /Count 1 +>> +endobj +3 0 obj << + /Type /Page + /Parent 2 0 R + /Annots [4 0 R] + /Contents [6 0 R] + /MediaBox [0 0 612 792] +>> +endobj +4 0 obj << + /Type /Annot + /Subtype /Widget + /F 4 + /FT /Btn + /Rect [ 75 80 125 120 ] + /T (PushButton) + /Ff 65536 + /H + /P + /AP << /N 5 0 R >> + /MK << /BG [ 1.0 0.0 0.0 ] >> +>> +endobj +5 0 obj << + /Subtype /Form + /BBox [ 0 40 50 00 ] + /Length 29 +>> +stream +q +0 0 1 rg +0 0 50 40 re B* +Q +endstream +endobj +6 0 obj << + /Length 18 +>> +stream +1 0 0 -1 0 792 cm +endstream +endobj +xref +0 7 +0000000000 65535 f +0000000015 00000 n +0000000108 00000 n +0000000171 00000 n +0000000286 00000 n +0000000478 00000 n +0000000598 00000 n +trailer << + /Root 1 0 R + /Size 7 +>> +startxref +667 +%%EOF |