aboutsummaryrefslogtreecommitdiffstats
path: root/qpdf
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2021-02-25 12:34:03 +0100
committerJay Berkenbilt <ejb@ql.org>2021-02-25 13:32:46 +0100
commita4d6589ff26007c966db8912e4dae1aa937a5968 (patch)
tree7eeba29b6e1b59a69f9e60105c1de4b587246473 /qpdf
parentec6719fd25ebd49c43142a607353bad5df7874aa (diff)
downloadqpdf-a4d6589ff26007c966db8912e4dae1aa937a5968.tar.zst
Have QPDFObjectHandle notice when replaceObject was called
This results in a performance penalty of 1% to 2% when replaceObject and swapObjects are never called and a somewhat larger penalty if they are called, but it's worth it to avoid very confusing behavior as discussed in depth in qpdf#507.
Diffstat (limited to 'qpdf')
-rw-r--r--qpdf/qtest/qpdf/test14-in.pdf34
-rw-r--r--qpdf/qtest/qpdf/test14-out.pdf28
-rw-r--r--qpdf/qtest/qpdf/test14.out4
-rw-r--r--qpdf/test_driver.cc20
4 files changed, 47 insertions, 39 deletions
diff --git a/qpdf/qtest/qpdf/test14-in.pdf b/qpdf/qtest/qpdf/test14-in.pdf
index 4d761020..d0cd490a 100644
--- a/qpdf/qtest/qpdf/test14-in.pdf
+++ b/qpdf/qtest/qpdf/test14-in.pdf
@@ -65,6 +65,7 @@ endobj
612
792
]
+ /OrigPage 2
/Parent 4 0 R
/Resources <<
/Font <<
@@ -86,6 +87,7 @@ endobj
612
792
]
+ /OrigPage 3
/Parent 4 0 R
/Resources <<
/Font <<
@@ -237,21 +239,21 @@ xref
0000000140 00000 n
0000000252 00000 n
0000000456 00000 n
-0000000661 00000 n
-0000000866 00000 n
-0000001084 00000 n
-0000001186 00000 n
-0000001206 00000 n
-0000001325 00000 n
-0000001384 00000 n
-0000001487 00000 n
-0000001507 00000 n
-0000001566 00000 n
-0000001669 00000 n
-0000001689 00000 n
-0000001748 00000 n
-0000001851 00000 n
-0000001871 00000 n
+0000000675 00000 n
+0000000894 00000 n
+0000001112 00000 n
+0000001214 00000 n
+0000001234 00000 n
+0000001353 00000 n
+0000001412 00000 n
+0000001515 00000 n
+0000001535 00000 n
+0000001594 00000 n
+0000001697 00000 n
+0000001717 00000 n
+0000001776 00000 n
+0000001879 00000 n
+0000001899 00000 n
trailer <<
/QArray 2 0 R
/QDict 3 0 R
@@ -260,5 +262,5 @@ trailer <<
/ID [<20eb74876a3e8212c1b4fd43153860b0><1bb7a926da191c58f675435d77997d21>]
>>
startxref
-1907
+1935
%%EOF
diff --git a/qpdf/qtest/qpdf/test14-out.pdf b/qpdf/qtest/qpdf/test14-out.pdf
index 315d174d..96c25fbd 100644
--- a/qpdf/qtest/qpdf/test14-out.pdf
+++ b/qpdf/qtest/qpdf/test14-out.pdf
@@ -16,10 +16,10 @@ endobj
<< /Contents 9 0 R /MediaBox [ 0 0 612 792 ] /Parent 4 0 R /Resources << /Font << /F1 10 0 R >> /ProcSet 11 0 R >> /Type /Page >>
endobj
6 0 obj
-<< /Contents 12 0 R /MediaBox [ 0 0 612 792 ] /Parent 4 0 R /Resources << /Font << /F1 10 0 R >> /ProcSet 13 0 R >> /Type /Page >>
+<< /Contents 12 0 R /MediaBox [ 0 0 612 792 ] /OrigPage 3 /Parent 4 0 R /Resources << /Font << /F1 10 0 R >> /ProcSet 13 0 R >> /Type /Page >>
endobj
7 0 obj
-<< /Contents 14 0 R /MediaBox [ 0 0 612 792 ] /Parent 4 0 R /Resources << /Font << /F1 10 0 R >> /ProcSet 15 0 R >> /Type /Page >>
+<< /Contents 14 0 R /MediaBox [ 0 0 612 792 ] /OrigPage 2 /Parent 4 0 R /Resources << /Font << /F1 10 0 R >> /ProcSet 15 0 R >> /Type /Page >>
endobj
8 0 obj
<< /Contents 16 0 R /MediaBox [ 0 0 612 792 ] /Parent 4 0 R /Resources << /Font << /F1 10 0 R >> /ProcSet 17 0 R >> /Type /Page >>
@@ -88,18 +88,18 @@ xref
0000000122 00000 n
0000000199 00000 n
0000000344 00000 n
-0000000490 00000 n
-0000000636 00000 n
-0000000782 00000 n
-0000000877 00000 n
-0000000985 00000 n
-0000001016 00000 n
-0000001112 00000 n
-0000001143 00000 n
-0000001239 00000 n
-0000001270 00000 n
-0000001366 00000 n
+0000000502 00000 n
+0000000660 00000 n
+0000000806 00000 n
+0000000901 00000 n
+0000001009 00000 n
+0000001040 00000 n
+0000001136 00000 n
+0000001167 00000 n
+0000001263 00000 n
+0000001294 00000 n
+0000001390 00000 n
trailer << /QArray 2 0 R /QDict 3 0 R /Root 1 0 R /Size 18 /ID [<20eb74876a3e8212c1b4fd43153860b0><31415926535897932384626433832795>] >>
startxref
-1397
+1421
%%EOF
diff --git a/qpdf/qtest/qpdf/test14.out b/qpdf/qtest/qpdf/test14.out
index 65b640b9..b6bce056 100644
--- a/qpdf/qtest/qpdf/test14.out
+++ b/qpdf/qtest/qpdf/test14.out
@@ -1,6 +1,6 @@
caught logic error as expected
-old dict: 1
-old dict: 1
+old dict: 2
+swapped array: /Array
new dict: 2
swapped array: /Array
array and dictionary contents are correct
diff --git a/qpdf/test_driver.cc b/qpdf/test_driver.cc
index 0ab25fb3..614d9025 100644
--- a/qpdf/test_driver.cc
+++ b/qpdf/test_driver.cc
@@ -740,7 +740,13 @@ void runtest(int n, char const* filename1, char const* arg2)
" not called 4-page file");
}
// Swap pages 2 and 3
- pdf.swapObjects(pages.at(1).getObjGen(), pages.at(2).getObjGen());
+ auto orig_page2 = pages.at(1);
+ auto orig_page3 = pages.at(2);
+ assert(orig_page2.getKey("/OrigPage").getIntValue() == 2);
+ assert(orig_page3.getKey("/OrigPage").getIntValue() == 3);
+ pdf.swapObjects(orig_page2.getObjGen(), orig_page3.getObjGen());
+ assert(orig_page2.getKey("/OrigPage").getIntValue() == 3);
+ assert(orig_page3.getKey("/OrigPage").getIntValue() == 2);
// Replace object and swap objects
QPDFObjectHandle trailer = pdf.getTrailer();
QPDFObjectHandle qdict = trailer.getKey("/QDict");
@@ -759,18 +765,18 @@ void runtest(int n, char const* filename1, char const* arg2)
std::cout << "caught logic error as expected" << std::endl;
}
pdf.replaceObject(qdict.getObjGen(), new_dict);
- // Now qdict still points to the old dictionary
- std::cout << "old dict: " << qdict.getKey("/Dict").getIntValue()
+ // Now qdict points to the new dictionary
+ std::cout << "old dict: " << qdict.getKey("/NewDict").getIntValue()
<< std::endl;
// Swap dict and array
pdf.swapObjects(qdict.getObjGen(), qarray.getObjGen());
- // Now qarray will resolve to new object but qdict is still
- // the old object
- std::cout << "old dict: " << qdict.getKey("/Dict").getIntValue()
+ // Now qarray will resolve to new object and qdict resolves to
+ // the array
+ std::cout << "swapped array: " << qdict.getArrayItem(0).getName()
<< std::endl;
std::cout << "new dict: " << qarray.getKey("/NewDict").getIntValue()
<< std::endl;
- // Reread qdict, now pointing to an array
+ // Reread qdict, still pointing to an array
qdict = pdf.getObjectByObjGen(qdict.getObjGen());
std::cout << "swapped array: " << qdict.getArrayItem(0).getName()
<< std::endl;