From 0a0eb92a71f2a6f396651a30a98b4c6a042b3847 Mon Sep 17 00:00:00 2001 From: m-holger Date: Tue, 4 Nov 2025 14:45:36 +0000 Subject: [PATCH] Refactor `QPDF::getRoot`: improve error handling for invalid trailer `/Root` and simplify logic. Update related test outputs and release notes. --- libqpdf/QPDF.cc | 16 ++++++++-------- manual/release-notes.rst | 4 ++++ qpdf/qtest/qpdf/c-oh-errors.out | 8 ++++---- qpdf/qtest/qpdf/test73.out | 2 +- 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc index 9e444ce..890a6d2 100644 --- a/libqpdf/QPDF.cc +++ b/libqpdf/QPDF.cc @@ -651,17 +651,17 @@ QPDF::getTrailer() QPDFObjectHandle QPDF::getRoot() { - QPDFObjectHandle root = m->trailer.getKey("/Root"); - if (!root.isDictionary()) { + Dictionary Root = m->trailer["/Root"]; + if (!Root) { throw m->c.damagedPDF("", -1, "unable to find /Root dictionary"); - } else if ( - // Check_mode is an interim solution to request #810 pending a more comprehensive review of - // the approach to more extensive checks and warning levels. - m->cf.check_mode() && !root.getKey("/Type").isNameAndEquals("/Catalog")) { + } + // Check_mode is an interim solution to request #810 pending a more comprehensive review of the + // approach to more extensive checks and warning levels. + if (m->cf.check_mode() && Name(Root["/Type"]) != "/Catalog") { warn(m->c.damagedPDF("", -1, "catalog /Type entry missing or invalid")); - root.replaceKey("/Type", "/Catalog"_qpdf); + Root.replaceKey("/Type", Name("/Catalog")); } - return root; + return Root.oh(); } std::map diff --git a/manual/release-notes.rst b/manual/release-notes.rst index 72c8e93..db330b8 100644 --- a/manual/release-notes.rst +++ b/manual/release-notes.rst @@ -65,6 +65,10 @@ more detail. - Other changes + - Calling ``QPDF::getRoot`` on a file with invalid trailer now throws a + ``damaged_pdf`` error with message "unable to find /Root dictionary" + rather than an internal error. + .. _r12-3-0-deprecate: - The following are believed to be not in use and have been deprecated. diff --git a/qpdf/qtest/qpdf/c-oh-errors.out b/qpdf/qtest/qpdf/c-oh-errors.out index aaeedef..c79544e 100644 --- a/qpdf/qtest/qpdf/c-oh-errors.out +++ b/qpdf/qtest/qpdf/c-oh-errors.out @@ -1,8 +1,8 @@ -get root: attempted to dereference an uninitialized QPDFObjectHandle - code: 1 - file: +get root: closed input source: unable to find /Root dictionary + code: 5 + file: closed input source pos: 0 - text: attempted to dereference an uninitialized QPDFObjectHandle + text: unable to find /Root dictionary bad parse: parsed object (offset 1): unknown token while reading object; treating as string code: 5 file: parsed object diff --git a/qpdf/qtest/qpdf/test73.out b/qpdf/qtest/qpdf/test73.out index ad6fb78..54e241a 100644 --- a/qpdf/qtest/qpdf/test73.out +++ b/qpdf/qtest/qpdf/test73.out @@ -1,3 +1,3 @@ -getRoot: attempted to dereference an uninitialized QPDFObjectHandle +getRoot: closed input source: unable to find /Root dictionary WARNING: closed input source: object 4/0: error reading object: QPDF operation attempted on a QPDF object with no input source. QPDF operations are invalid before processFile (or another process method) or after closeInputSource test 73 done -- libgit2 0.21.4