From 9abd73ff795483d4367ad8c4d079f00386c8dea1 Mon Sep 17 00:00:00 2001 From: m-holger Date: Wed, 30 Jul 2025 14:17:25 +0100 Subject: [PATCH] Improve `QPDFParser` handling of invalid indirect references by enhancing associated warnings --- libqpdf/QPDFParser.cc | 4 +++- qpdf/qtest/qpdf/issue-101.out | 2 ++ qpdf/qtest/qpdf/issue-118.out | 1 + qpdf/qtest/qpdf/issue-335a.out | 16 ++++++++++++---- qpdf/qtest/qpdf/issue-51.out | 1 + qpdf/qtest/qpdf/issue-99.out | 2 ++ qpdf/qtest/qpdf/parse-object.out | 5 +++++ 7 files changed, 26 insertions(+), 5 deletions(-) diff --git a/libqpdf/QPDFParser.cc b/libqpdf/QPDFParser.cc index 7e823cd..7b6d855 100644 --- a/libqpdf/QPDFParser.cc +++ b/libqpdf/QPDFParser.cc @@ -320,7 +320,9 @@ QPDFParser::parseRemainder(bool content_stream) if (!(id < 1 || gen < 0 || gen >= 65535)) { add(ParseGuard::getObject(context, id, gen, parse_pdf)); } else { - addNull(); + add_bad_null( + "treating bad indirect reference (" + std::to_string(id) + " " + + std::to_string(gen) + " R) as null"); } int_count = 0; continue; diff --git a/qpdf/qtest/qpdf/issue-101.out b/qpdf/qtest/qpdf/issue-101.out index f9567b7..ae8db9d 100644 --- a/qpdf/qtest/qpdf/issue-101.out +++ b/qpdf/qtest/qpdf/issue-101.out @@ -30,6 +30,8 @@ WARNING: issue-101.pdf (trailer, offset 1508): stream keyword found in trailer WARNING: issue-101.pdf (trailer, offset 1438): recovered trailer has no /Root entry WARNING: issue-101.pdf (object 2 0, offset 244): unknown token while reading object; treating as null WARNING: issue-101.pdf (object 2 0, offset 29): dictionary has duplicated key /Parent; last occurrence overrides earlier ones +WARNING: issue-101.pdf (object 2 0, offset 333): treating bad indirect reference (0 0 R) as null +WARNING: issue-101.pdf (object 5 0, offset 1247): treating bad indirect reference (0 0 R) as null WARNING: issue-101.pdf (object 5 0, offset 1242): dictionary ended prematurely; using null as value for last key WARNING: issue-101.pdf (object 5 0, offset 1242): expected dictionary keys but found non-name objects; ignoring WARNING: issue-101.pdf (object 7 0, offset 3855): unknown token while reading object; treating as null diff --git a/qpdf/qtest/qpdf/issue-118.out b/qpdf/qtest/qpdf/issue-118.out index 1dc9df1..f1c9f2c 100644 --- a/qpdf/qtest/qpdf/issue-118.out +++ b/qpdf/qtest/qpdf/issue-118.out @@ -1,4 +1,5 @@ WARNING: issue-118.pdf: can't find PDF header +WARNING: issue-118.pdf (xref stream: object 8 0, offset 720): treating bad indirect reference (0 0 R) as null WARNING: issue-118.pdf (xref stream, offset 732): self-referential object stream 2 WARNING: issue-118.pdf (xref stream, offset 732): object stream id 12336 for object 3 is impossibly large WARNING: issue-118.pdf (xref stream, offset 732): object stream id 12336 for object 4 is impossibly large diff --git a/qpdf/qtest/qpdf/issue-335a.out b/qpdf/qtest/qpdf/issue-335a.out index 6771fe6..33e1c37 100644 --- a/qpdf/qtest/qpdf/issue-335a.out +++ b/qpdf/qtest/qpdf/issue-335a.out @@ -39,12 +39,14 @@ WARNING: issue-335a.pdf (trailer, offset 22844): expected dictionary keys but fo WARNING: issue-335a.pdf (trailer, offset 22880): stream keyword found in trailer WARNING: issue-335a.pdf (trailer, offset 22840): recovered trailer has no /Root entry WARNING: issue-335a.pdf (trailer, offset 22702): unknown token while reading object; treating as null +WARNING: issue-335a.pdf (trailer, offset 22713): treating bad indirect reference (0 0 R) as null WARNING: issue-335a.pdf (trailer, offset 22701): expected dictionary keys but found non-name objects; ignoring WARNING: issue-335a.pdf (trailer, offset 22746): stream keyword found in trailer WARNING: issue-335a.pdf (trailer, offset 22697): recovered trailer has no /Root entry WARNING: issue-335a.pdf (trailer, offset 22687): unknown token while reading object; treating as null WARNING: issue-335a.pdf (trailer, offset 22690): unknown token while reading object; treating as null WARNING: issue-335a.pdf (trailer, offset 22702): unknown token while reading object; treating as null +WARNING: issue-335a.pdf (trailer, offset 22713): treating bad indirect reference (0 0 R) as null WARNING: issue-335a.pdf (trailer, offset 22701): expected dictionary keys but found non-name objects; ignoring WARNING: issue-335a.pdf (trailer, offset 22740): unknown token while reading object; treating as null WARNING: issue-335a.pdf (trailer, offset 22748): unknown token while reading object; treating as null @@ -58,6 +60,7 @@ WARNING: issue-335a.pdf (trailer, offset 22675): unknown token while reading obj WARNING: issue-335a.pdf (trailer, offset 22687): unknown token while reading object; treating as null WARNING: issue-335a.pdf (trailer, offset 22690): unknown token while reading object; treating as null WARNING: issue-335a.pdf (trailer, offset 22702): unknown token while reading object; treating as null +WARNING: issue-335a.pdf (trailer, offset 22713): treating bad indirect reference (0 0 R) as null WARNING: issue-335a.pdf (trailer, offset 22701): expected dictionary keys but found non-name objects; ignoring WARNING: issue-335a.pdf (trailer, offset 22740): unknown token while reading object; treating as null WARNING: issue-335a.pdf (trailer, offset 22748): unknown token while reading object; treating as null @@ -66,6 +69,8 @@ WARNING: issue-335a.pdf (trailer, offset 22791): unknown token while reading obj WARNING: issue-335a.pdf (trailer, offset 22794): unexpected > WARNING: issue-335a.pdf (trailer, offset 22794): too many errors; giving up on reading object WARNING: issue-335a.pdf (trailer, offset 22437): unknown token while reading object; treating as null +WARNING: issue-335a.pdf (trailer, offset 22448): treating bad indirect reference (0 0 R) as null +WARNING: issue-335a.pdf (trailer, offset 22471): treating bad indirect reference (20 -1 R) as null WARNING: issue-335a.pdf (trailer, offset 22436): expected dictionary keys but found non-name objects; ignoring WARNING: issue-335a.pdf (trailer, offset 22482): stream keyword found in trailer WARNING: issue-335a.pdf (trailer, offset 22432): recovered trailer has no /Root entry @@ -98,27 +103,30 @@ WARNING: issue-335a.pdf (trailer, offset 22134): stream keyword found in trailer WARNING: issue-335a.pdf (trailer, offset 22083): recovered trailer has no /Root entry WARNING: issue-335a.pdf (trailer, offset 22000): invalid character (t) in hexstring WARNING: issue-335a.pdf (trailer, offset 21937): unknown token while reading object; treating as null +WARNING: issue-335a.pdf (trailer, offset 21948): treating bad indirect reference (0 0 R) as null WARNING: issue-335a.pdf (trailer, offset 21962): unknown token while reading object; treating as null WARNING: issue-335a.pdf (trailer, offset 21991): unknown token while reading object; treating as null WARNING: issue-335a.pdf (trailer, offset 22000): invalid character (t) in hexstring WARNING: issue-335a.pdf (trailer, offset 22003): unknown token while reading object; treating as null +WARNING: issue-335a.pdf (trailer, offset 22026): treating bad indirect reference (-4 0 R) as null WARNING: issue-335a.pdf (trailer, offset 21936): dictionary has duplicated key /Length; last occurrence overrides earlier ones WARNING: issue-335a.pdf (trailer, offset 22028): unexpected > WARNING: issue-335a.pdf (trailer, offset 22030): unknown token while reading object; treating as null -WARNING: issue-335a.pdf (trailer, offset 22038): unknown token while reading object; treating as null -WARNING: issue-335a.pdf (trailer, offset 22038): too many errors; giving up on reading object +WARNING: issue-335a.pdf (trailer, offset 22030): too many errors; giving up on reading object WARNING: issue-335a.pdf (trailer, offset 21918): unknown token while reading object; treating as null WARNING: issue-335a.pdf (trailer, offset 21925): unknown token while reading object; treating as null WARNING: issue-335a.pdf (trailer, offset 21937): unknown token while reading object; treating as null +WARNING: issue-335a.pdf (trailer, offset 21948): treating bad indirect reference (0 0 R) as null WARNING: issue-335a.pdf (trailer, offset 21962): unknown token while reading object; treating as null WARNING: issue-335a.pdf (trailer, offset 21991): unknown token while reading object; treating as null WARNING: issue-335a.pdf (trailer, offset 22000): invalid character (t) in hexstring WARNING: issue-335a.pdf (trailer, offset 22003): unknown token while reading object; treating as null +WARNING: issue-335a.pdf (trailer, offset 22026): treating bad indirect reference (-4 0 R) as null WARNING: issue-335a.pdf (trailer, offset 21936): dictionary has duplicated key /Length; last occurrence overrides earlier ones WARNING: issue-335a.pdf (trailer, offset 22028): unexpected > -WARNING: issue-335a.pdf (trailer, offset 22030): unknown token while reading object; treating as null -WARNING: issue-335a.pdf (trailer, offset 22030): too many errors; giving up on reading object +WARNING: issue-335a.pdf (trailer, offset 22028): too many errors; giving up on reading object WARNING: issue-335a.pdf (trailer, offset 21837): unknown token while reading object; treating as null +WARNING: issue-335a.pdf (trailer, offset 21861): treating bad indirect reference (0 0 R) as null WARNING: issue-335a.pdf (trailer, offset 21850): expected dictionary keys but found non-name objects; ignoring WARNING: issue-335a.pdf (trailer, offset 21892): unknown token while reading object; treating as null WARNING: issue-335a.pdf (trailer, offset 21900): unknown token while reading object; treating as null diff --git a/qpdf/qtest/qpdf/issue-51.out b/qpdf/qtest/qpdf/issue-51.out index 2777ab6..eecb96f 100644 --- a/qpdf/qtest/qpdf/issue-51.out +++ b/qpdf/qtest/qpdf/issue-51.out @@ -1,5 +1,6 @@ WARNING: issue-51.pdf: can't find PDF header WARNING: issue-51.pdf: reported number of objects (0) is not one plus the highest object number (8) +WARNING: issue-51.pdf (object 7 0, offset 500): treating bad indirect reference (0 0 R) as null WARNING: issue-51.pdf (object 7 0, offset 476): dictionary has duplicated key /0000; last occurrence overrides earlier ones WARNING: issue-51.pdf (object 7 0, offset 553): expected endobj issue-51.pdf: unable to find page tree diff --git a/qpdf/qtest/qpdf/issue-99.out b/qpdf/qtest/qpdf/issue-99.out index d800d79..a9a454e 100644 --- a/qpdf/qtest/qpdf/issue-99.out +++ b/qpdf/qtest/qpdf/issue-99.out @@ -1,6 +1,7 @@ WARNING: issue-99.pdf: file is damaged WARNING: issue-99.pdf (offset 3526): xref not found WARNING: issue-99.pdf: Attempting to reconstruct cross-reference table +WARNING: issue-99.pdf (trailer, offset 4635): treating bad indirect reference (0 0 R) as null WARNING: issue-99.pdf (trailer, offset 4613): recovered trailer has no /Root entry WARNING: issue-99.pdf (object 1 0, offset 775): unknown token while reading object; treating as null WARNING: issue-99.pdf (object 1 0, offset 795): unknown token while reading object; treating as null @@ -11,6 +12,7 @@ WARNING: issue-99.pdf (object 1 0, offset 855): too many errors; giving up on re WARNING: issue-99.pdf (object 2 0, offset 64): expected endobj WARNING: issue-99.pdf (object 5 0, offset 2452): unknown token while reading object; treating as string WARNING: issue-99.pdf (object 6 0, offset 2506): unexpected array close token; giving up on reading object +WARNING: issue-99.pdf (object 8 0, offset 4281): treating bad indirect reference (0 0 R) as null WARNING: issue-99.pdf (object 10 0, offset 3708): expected dictionary keys but found non-name objects; ignoring WARNING: issue-99.pdf (object 11 0, offset 4485): unknown token while reading object; treating as null WARNING: issue-99.pdf (object 11 0, offset 4497): unexpected array close token; giving up on reading object diff --git a/qpdf/qtest/qpdf/parse-object.out b/qpdf/qtest/qpdf/parse-object.out index 71e0bf5..16efee5 100644 --- a/qpdf/qtest/qpdf/parse-object.out +++ b/qpdf/qtest/qpdf/parse-object.out @@ -6,4 +6,9 @@ WARNING: parsed object: treating unexpected brace token as null WARNING: parsed object: treating unexpected brace token as null WARNING: parsed object: unexpected dictionary close token WARNING: bad-parse.qdf (object 7 0, offset 1121): unexpected EOF +WARNING: parsed object (offset 5): treating bad indirect reference (0 0 R) as null +WARNING: parsed object (offset 12): treating bad indirect reference (-1 0 R) as null +WARNING: parsed object (offset 22): treating bad indirect reference (1 65535 R) as null +WARNING: parsed object (offset 33): treating bad indirect reference (1 100000 R) as null +WARNING: parsed object (offset 40): treating bad indirect reference (1 -1 R) as null test 31 done -- libgit2 0.21.4