diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc index 9027c7fd..bd591a51 100644 --- a/libqpdf/QPDF.cc +++ b/libqpdf/QPDF.cc @@ -2058,27 +2058,27 @@ QPDF::reserveObjects(QPDFObjectHandle foreign, ObjCopier& obj_copier, bool top) if (foreign.isIndirect()) { QPDFObjGen foreign_og(foreign.getObjGen()); + if (!obj_copier.visiting.add(foreign_og)) { + QTC::TC("qpdf", "QPDF loop reserving objects"); + return; + } if (obj_copier.object_map.count(foreign_og) > 0) { QTC::TC("qpdf", "QPDF already reserved object"); - if (obj_copier.visiting.count(foreign_og)) { - QTC::TC("qpdf", "QPDF loop reserving objects"); + if (!(top && foreign.isPageObject() && obj_copier.object_map[foreign_og].isNull())) { + obj_copier.visiting.erase(foreign); + return; } - return; - } - if (!obj_copier.visiting.add(foreign_og)) { - return; - } - QTC::TC("qpdf", "QPDF copy indirect"); - if (obj_copier.object_map.count(foreign_og) == 0) { + } else { + QTC::TC("qpdf", "QPDF copy indirect"); obj_copier.object_map[foreign_og] = foreign.isStream() ? newStream() : newIndirectNull(); if ((!top) && foreign.isPageObject()) { QTC::TC("qpdf", "QPDF not crossing page boundary"); - obj_copier.visiting.erase(foreign); + obj_copier.visiting.erase(foreign_og); return; } - obj_copier.to_copy.push_back(foreign); } + obj_copier.to_copy.push_back(foreign); } if (foreign_tc == ::ot_array) { diff --git a/qpdf/qtest/copy-annotations.test b/qpdf/qtest/copy-annotations.test index d7c22438..6279ca5a 100644 --- a/qpdf/qtest/copy-annotations.test +++ b/qpdf/qtest/copy-annotations.test @@ -14,7 +14,7 @@ cleanup(); my $td = new TestDriver('copy-annotations'); -my $n_tests = 43; +my $n_tests = 45; $td->runtest("complex copy annotations", {$td->COMMAND => @@ -206,5 +206,14 @@ $td->runtest("check output", {$td->FILE => "split-out-1.pdf"}, {$td->FILE => "direct-dr-out.pdf"}); +$td->runtest("Foreign link annotations", + {$td->COMMAND => + "qpdf --empty --pages link-annots.pdf -- --qdf --static-id --no-original-object-ids a.pdf"}, + {$td->STRING => "", $td->EXIT_STATUS => 0}, + $td->NORMALIZE_NEWLINES); +$td->runtest("check output", + {$td->FILE => "link-annots.pdf"}, + {$td->FILE => "a.pdf"}); + cleanup(); $td->report($n_tests); diff --git a/qpdf/qtest/qpdf/link-annots.pdf b/qpdf/qtest/qpdf/link-annots.pdf new file mode 100644 index 00000000..6f4bc570 --- /dev/null +++ b/qpdf/qtest/qpdf/link-annots.pdf @@ -0,0 +1,790 @@ +%PDF-1.6 +%¿÷¢þ +%QDF-1.0 + +1 0 obj +<< + /Pages 2 0 R + /Type /Catalog +>> +endobj + +2 0 obj +<< + /Count 4 + /Kids [ + 3 0 R + 4 0 R + 5 0 R + 6 0 R + ] + /Type /Pages +>> +endobj + +%% Page 1 +3 0 obj +<< + /Annots [ + 7 0 R + 8 0 R + 9 0 R + 10 0 R + ] + /Contents 11 0 R + /Group << + /CS /DeviceRGB + /I true + /S /Transparency + >> + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 2 0 R + /Resources << + /Font << + /F2 13 0 R + >> + /ProcSet [ + /PDF + /Text + ] + >> + /Type /Page +>> +endobj + +%% Page 2 +4 0 obj +<< + /Annots [ + 14 0 R + 15 0 R + 16 0 R + 17 0 R + ] + /Contents 18 0 R + /Group << + /CS /DeviceRGB + /I true + /S /Transparency + >> + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 2 0 R + /Resources << + /Font << + /F2 13 0 R + >> + /ProcSet [ + /PDF + /Text + ] + >> + /Type /Page +>> +endobj + +%% Page 3 +5 0 obj +<< + /Annots [ + 20 0 R + 21 0 R + 22 0 R + 23 0 R + ] + /Contents 24 0 R + /Group << + /CS /DeviceRGB + /I true + /S /Transparency + >> + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 2 0 R + /Resources << + /Font << + /F2 13 0 R + >> + /ProcSet [ + /PDF + /Text + ] + >> + /Type /Page +>> +endobj + +%% Page 4 +6 0 obj +<< + /Annots [ + 26 0 R + 27 0 R + 28 0 R + 29 0 R + ] + /Contents 30 0 R + /Group << + /CS /DeviceRGB + /I true + /S /Transparency + >> + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 2 0 R + /Resources << + /Font << + /F2 13 0 R + >> + /ProcSet [ + /PDF + /Text + ] + >> + /Type /Page +>> +endobj + +7 0 obj +<< + /Border [ + 0 + 0 + 0 + ] + /Dest [ + 3 0 R + /XYZ + 56.7 + 773.189 + 0 + ] + /Rect [ + 54 + 695 + 100 + 708 + ] + /Subtype /Link + /Type /Annot +>> +endobj + +8 0 obj +<< + /Border [ + 0 + 0 + 0 + ] + /Dest [ + 4 0 R + /XYZ + 56.7 + 773.189 + 0 + ] + /Rect [ + 54 + 645 + 100 + 658 + ] + /Subtype /Link + /Type /Annot +>> +endobj + +9 0 obj +<< + /Border [ + 0 + 0 + 0 + ] + /Dest [ + 5 0 R + /XYZ + 56.7 + 773.189 + 0 + ] + /Rect [ + 54 + 595 + 100 + 608 + ] + /Subtype /Link + /Type /Annot +>> +endobj + +10 0 obj +<< + /Border [ + 0 + 0 + 0 + ] + /Dest [ + 6 0 R + /XYZ + 56.7 + 773.189 + 0 + ] + /Rect [ + 54 + 545 + 100 + 558 + ] + /Subtype /Link + /Type /Annot +>> +endobj + +%% Contents for page 1 +11 0 obj +<< + /Length 12 0 R +>> +stream +0.1 w + +q 0 0 0 rg +BT +55 750 Td /F2 18 Tf (Page 1) Tj +ET +Q + +q 0 0 0.5019607843 rg +BT +55 700 Td /F2 12 Tf (Page 1) Tj +ET +Q + +q 0 0 0.5019607843 rg +BT +55 650 Td /F2 12 Tf (Page 2) Tj +ET +Q + +q 0 0 0.5019607843 rg +BT +55 600 Td /F2 12 Tf (Page 3) Tj +ET +Q + +q 0 0 0.5019607843 rg +BT +55 550 Td /F2 12 Tf (Page 4) Tj +ET +Q +endstream +endobj + +12 0 obj +314 +endobj + +13 0 obj +<< + /BaseFont /Courier + /Subtype /TrueType + /Type /Font +>> +endobj + +14 0 obj +<< + /Border [ + 0 + 0 + 0 + ] + /Dest [ + 3 0 R + /XYZ + 56.7 + 773.189 + 0 + ] + /Rect [ + 54 + 695 + 100 + 708 + ] + /Subtype /Link + /Type /Annot +>> +endobj + +15 0 obj +<< + /Border [ + 0 + 0 + 0 + ] + /Dest [ + 4 0 R + /XYZ + 56.7 + 773.189 + 0 + ] + /Rect [ + 54 + 645 + 100 + 658 + ] + /Subtype /Link + /Type /Annot +>> +endobj + +16 0 obj +<< + /Border [ + 0 + 0 + 0 + ] + /Dest [ + 5 0 R + /XYZ + 56.7 + 773.189 + 0 + ] + /Rect [ + 54 + 595 + 100 + 608 + ] + /Subtype /Link + /Type /Annot +>> +endobj + +17 0 obj +<< + /Border [ + 0 + 0 + 0 + ] + /Dest [ + 6 0 R + /XYZ + 56.7 + 773.189 + 0 + ] + /Rect [ + 54 + 545 + 100 + 558 + ] + /Subtype /Link + /Type /Annot +>> +endobj + +%% Contents for page 2 +18 0 obj +<< + /Length 19 0 R +>> +stream +0.1 w + +q 0 0 0 rg +BT +55 750 Td /F2 18 Tf (Page 2) Tj +ET +Q + +q 0 0 0.5019607843 rg +BT +55 700 Td /F2 12 Tf (Page 1) Tj +ET +Q + +q 0 0 0.5019607843 rg +BT +55 650 Td /F2 12 Tf (Page 2) Tj +ET +Q + +q 0 0 0.5019607843 rg +BT +55 600 Td /F2 12 Tf (Page 3) Tj +ET +Q + +q 0 0 0.5019607843 rg +BT +55 550 Td /F2 12 Tf (Page 4) Tj +ET +Q +endstream +endobj + +19 0 obj +314 +endobj + +20 0 obj +<< + /Border [ + 0 + 0 + 0 + ] + /Dest [ + 3 0 R + /XYZ + 56.7 + 773.189 + 0 + ] + /Rect [ + 54 + 695 + 100 + 708 + ] + /Subtype /Link + /Type /Annot +>> +endobj + +21 0 obj +<< + /Border [ + 0 + 0 + 0 + ] + /Dest [ + 4 0 R + /XYZ + 56.7 + 773.189 + 0 + ] + /Rect [ + 54 + 645 + 100 + 658 + ] + /Subtype /Link + /Type /Annot +>> +endobj + +22 0 obj +<< + /Border [ + 0 + 0 + 0 + ] + /Dest [ + 5 0 R + /XYZ + 56.7 + 773.189 + 0 + ] + /Rect [ + 54 + 595 + 100 + 608 + ] + /Subtype /Link + /Type /Annot +>> +endobj + +23 0 obj +<< + /Border [ + 0 + 0 + 0 + ] + /Dest [ + 6 0 R + /XYZ + 56.7 + 773.189 + 0 + ] + /Rect [ + 54 + 545 + 100 + 558 + ] + /Subtype /Link + /Type /Annot +>> +endobj + +%% Contents for page 3 +24 0 obj +<< + /Length 25 0 R +>> +stream +0.1 w + +q 0 0 0 rg +BT +55 750 Td /F2 18 Tf (Page 3) Tj +ET +Q + +q 0 0 0.5019607843 rg +BT +55 700 Td /F2 12 Tf (Page 1) Tj +ET +Q + +q 0 0 0.5019607843 rg +BT +55 650 Td /F2 12 Tf (Page 2) Tj +ET +Q + +q 0 0 0.5019607843 rg +BT +55 600 Td /F2 12 Tf (Page 3) Tj +ET +Q + +q 0 0 0.5019607843 rg +BT +55 550 Td /F2 12 Tf (Page 4) Tj +ET +Q +endstream +endobj + +25 0 obj +314 +endobj + +26 0 obj +<< + /Border [ + 0 + 0 + 0 + ] + /Dest [ + 3 0 R + /XYZ + 56.7 + 773.189 + 0 + ] + /Rect [ + 54 + 695 + 100 + 708 + ] + /Subtype /Link + /Type /Annot +>> +endobj + +27 0 obj +<< + /Border [ + 0 + 0 + 0 + ] + /Dest [ + 4 0 R + /XYZ + 56.7 + 773.189 + 0 + ] + /Rect [ + 54 + 645 + 100 + 658 + ] + /Subtype /Link + /Type /Annot +>> +endobj + +28 0 obj +<< + /Border [ + 0 + 0 + 0 + ] + /Dest [ + 5 0 R + /XYZ + 56.7 + 773.189 + 0 + ] + /Rect [ + 54 + 595 + 100 + 608 + ] + /Subtype /Link + /Type /Annot +>> +endobj + +29 0 obj +<< + /Border [ + 0 + 0 + 0 + ] + /Dest [ + 6 0 R + /XYZ + 56.7 + 773.189 + 0 + ] + /Rect [ + 54 + 545 + 100 + 558 + ] + /Subtype /Link + /Type /Annot +>> +endobj + +%% Contents for page 4 +30 0 obj +<< + /Length 31 0 R +>> +stream +0.1 w + +q 0 0 0 rg +BT +55 750 Td /F2 18 Tf (Page 4) Tj +ET +Q + +q 0 0 0.5019607843 rg +BT +55 700 Td /F2 12 Tf (Page 1) Tj +ET +Q + +q 0 0 0.5019607843 rg +BT +55 650 Td /F2 12 Tf (Page 2) Tj +ET +Q + +q 0 0 0.5019607843 rg +BT +55 600 Td /F2 12 Tf (Page 3) Tj +ET +Q + +q 0 0 0.5019607843 rg +BT +55 550 Td /F2 12 Tf (Page 4) Tj +ET +Q +endstream +endobj + +31 0 obj +314 +endobj + +xref +0 32 +0000000000 65535 f +0000000025 00000 n +0000000079 00000 n +0000000191 00000 n +0000000546 00000 n +0000000904 00000 n +0000001262 00000 n +0000001610 00000 n +0000001803 00000 n +0000001996 00000 n +0000002189 00000 n +0000002406 00000 n +0000002777 00000 n +0000002798 00000 n +0000002877 00000 n +0000003071 00000 n +0000003265 00000 n +0000003459 00000 n +0000003676 00000 n +0000004047 00000 n +0000004068 00000 n +0000004262 00000 n +0000004456 00000 n +0000004650 00000 n +0000004867 00000 n +0000005238 00000 n +0000005259 00000 n +0000005453 00000 n +0000005647 00000 n +0000005841 00000 n +0000006058 00000 n +0000006429 00000 n +trailer << + /Root 1 0 R + /Size 32 + /ID [<31415926535897932384626433832795><31415926535897932384626433832795>] +>> +startxref +6450 +%%EOF