summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fpdfsdk/fpdf_flatten.cpp47
-rw-r--r--fpdfsdk/fpdf_flatten_embeddertest.cpp17
-rw-r--r--testing/resources/bug_890322.in1
-rw-r--r--testing/resources/bug_890322.pdf5
-rw-r--r--testing/resources/bug_896366.in60
-rw-r--r--testing/resources/bug_896366.pdf73
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