Commit 0a0eb92a71f2a6f396651a30a98b4c6a042b3847
1 parent
1831a2fe
Refactor `QPDF::getRoot`: improve error handling for invalid trailer `/Root` and…
… simplify logic. Update related test outputs and release notes.
Showing
4 changed files
with
17 additions
and
13 deletions
libqpdf/QPDF.cc
| @@ -651,17 +651,17 @@ QPDF::getTrailer() | @@ -651,17 +651,17 @@ QPDF::getTrailer() | ||
| 651 | QPDFObjectHandle | 651 | QPDFObjectHandle |
| 652 | QPDF::getRoot() | 652 | QPDF::getRoot() |
| 653 | { | 653 | { |
| 654 | - QPDFObjectHandle root = m->trailer.getKey("/Root"); | ||
| 655 | - if (!root.isDictionary()) { | 654 | + Dictionary Root = m->trailer["/Root"]; |
| 655 | + if (!Root) { | ||
| 656 | throw m->c.damagedPDF("", -1, "unable to find /Root dictionary"); | 656 | throw m->c.damagedPDF("", -1, "unable to find /Root dictionary"); |
| 657 | - } else if ( | ||
| 658 | - // Check_mode is an interim solution to request #810 pending a more comprehensive review of | ||
| 659 | - // the approach to more extensive checks and warning levels. | ||
| 660 | - m->cf.check_mode() && !root.getKey("/Type").isNameAndEquals("/Catalog")) { | 657 | + } |
| 658 | + // Check_mode is an interim solution to request #810 pending a more comprehensive review of the | ||
| 659 | + // approach to more extensive checks and warning levels. | ||
| 660 | + if (m->cf.check_mode() && Name(Root["/Type"]) != "/Catalog") { | ||
| 661 | warn(m->c.damagedPDF("", -1, "catalog /Type entry missing or invalid")); | 661 | warn(m->c.damagedPDF("", -1, "catalog /Type entry missing or invalid")); |
| 662 | - root.replaceKey("/Type", "/Catalog"_qpdf); | 662 | + Root.replaceKey("/Type", Name("/Catalog")); |
| 663 | } | 663 | } |
| 664 | - return root; | 664 | + return Root.oh(); |
| 665 | } | 665 | } |
| 666 | 666 | ||
| 667 | std::map<QPDFObjGen, QPDFXRefEntry> | 667 | std::map<QPDFObjGen, QPDFXRefEntry> |
manual/release-notes.rst
| @@ -65,6 +65,10 @@ more detail. | @@ -65,6 +65,10 @@ more detail. | ||
| 65 | 65 | ||
| 66 | - Other changes | 66 | - Other changes |
| 67 | 67 | ||
| 68 | + - Calling ``QPDF::getRoot`` on a file with invalid trailer now throws a | ||
| 69 | + ``damaged_pdf`` error with message "unable to find /Root dictionary" | ||
| 70 | + rather than an internal error. | ||
| 71 | + | ||
| 68 | .. _r12-3-0-deprecate: | 72 | .. _r12-3-0-deprecate: |
| 69 | 73 | ||
| 70 | - The following are believed to be not in use and have been deprecated. | 74 | - The following are believed to be not in use and have been deprecated. |
qpdf/qtest/qpdf/c-oh-errors.out
| 1 | -get root: attempted to dereference an uninitialized QPDFObjectHandle | ||
| 2 | - code: 1 | ||
| 3 | - file: | 1 | +get root: closed input source: unable to find /Root dictionary |
| 2 | + code: 5 | ||
| 3 | + file: closed input source | ||
| 4 | pos: 0 | 4 | pos: 0 |
| 5 | - text: attempted to dereference an uninitialized QPDFObjectHandle | 5 | + text: unable to find /Root dictionary |
| 6 | bad parse: parsed object (offset 1): unknown token while reading object; treating as string | 6 | bad parse: parsed object (offset 1): unknown token while reading object; treating as string |
| 7 | code: 5 | 7 | code: 5 |
| 8 | file: parsed object | 8 | file: parsed object |
qpdf/qtest/qpdf/test73.out
| 1 | -getRoot: attempted to dereference an uninitialized QPDFObjectHandle | 1 | +getRoot: closed input source: unable to find /Root dictionary |
| 2 | 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 | 2 | 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 |
| 3 | test 73 done | 3 | test 73 done |