Commit c47e332dbfdd35b0c52cf41a122fa9cea348736f

Authored by m-holger
1 parent 58ed11f2

Allow null `callbacks` in content stream handling

Introduce null checks for `callbacks` in `QPDFObjectHandle` to allow content streams to be parsed without ParserCallbacks. Update `QPDFJob` to pass `nullptr` instead of `DiscardContents` for parsing.
fuzz/qpdf_crypt_fuzzer.cc
@@ -13,20 +13,6 @@ @@ -13,20 +13,6 @@
13 13
14 #include <cstdlib> 14 #include <cstdlib>
15 15
16 -class DiscardContents: public QPDFObjectHandle::ParserCallbacks  
17 -{  
18 - public:  
19 - ~DiscardContents() override = default;  
20 - void  
21 - handleObject(QPDFObjectHandle) override  
22 - {  
23 - }  
24 - void  
25 - handleEOF() override  
26 - {  
27 - }  
28 -};  
29 -  
30 class FuzzHelper 16 class FuzzHelper
31 { 17 {
32 public: 18 public:
fuzz/qpdf_crypt_insecure_fuzzer.cc
@@ -12,20 +12,6 @@ @@ -12,20 +12,6 @@
12 #include <qpdf/QUtil.hh> 12 #include <qpdf/QUtil.hh>
13 #include <cstdlib> 13 #include <cstdlib>
14 14
15 -class DiscardContents: public QPDFObjectHandle::ParserCallbacks  
16 -{  
17 - public:  
18 - ~DiscardContents() override = default;  
19 - void  
20 - handleObject(QPDFObjectHandle) override  
21 - {  
22 - }  
23 - void  
24 - handleEOF() override  
25 - {  
26 - }  
27 -};  
28 -  
29 class FuzzHelper 15 class FuzzHelper
30 { 16 {
31 public: 17 public:
fuzz/qpdf_fuzzer.cc
@@ -12,20 +12,6 @@ @@ -12,20 +12,6 @@
12 #include <qpdf/QUtil.hh> 12 #include <qpdf/QUtil.hh>
13 #include <cstdlib> 13 #include <cstdlib>
14 14
15 -class DiscardContents: public QPDFObjectHandle::ParserCallbacks  
16 -{  
17 - public:  
18 - ~DiscardContents() override = default;  
19 - void  
20 - handleObject(QPDFObjectHandle) override  
21 - {  
22 - }  
23 - void  
24 - handleEOF() override  
25 - {  
26 - }  
27 -};  
28 -  
29 class FuzzHelper 15 class FuzzHelper
30 { 16 {
31 public: 17 public:
fuzz/qpdf_lin_fuzzer.cc
@@ -12,20 +12,6 @@ @@ -12,20 +12,6 @@
12 #include <qpdf/QUtil.hh> 12 #include <qpdf/QUtil.hh>
13 #include <cstdlib> 13 #include <cstdlib>
14 14
15 -class DiscardContents: public QPDFObjectHandle::ParserCallbacks  
16 -{  
17 - public:  
18 - ~DiscardContents() override = default;  
19 - void  
20 - handleObject(QPDFObjectHandle) override  
21 - {  
22 - }  
23 - void  
24 - handleEOF() override  
25 - {  
26 - }  
27 -};  
28 -  
29 class FuzzHelper 15 class FuzzHelper
30 { 16 {
31 public: 17 public:
fuzz/qpdf_outlines_fuzzer.cc
@@ -12,20 +12,6 @@ @@ -12,20 +12,6 @@
12 #include <qpdf/QUtil.hh> 12 #include <qpdf/QUtil.hh>
13 #include <cstdlib> 13 #include <cstdlib>
14 14
15 -class DiscardContents: public QPDFObjectHandle::ParserCallbacks  
16 -{  
17 - public:  
18 - ~DiscardContents() override = default;  
19 - void  
20 - handleObject(QPDFObjectHandle) override  
21 - {  
22 - }  
23 - void  
24 - handleEOF() override  
25 - {  
26 - }  
27 -};  
28 -  
29 class FuzzHelper 15 class FuzzHelper
30 { 16 {
31 public: 17 public:
fuzz/qpdf_page_fuzzer.cc
@@ -17,20 +17,6 @@ @@ -17,20 +17,6 @@
17 #include <cstdlib> 17 #include <cstdlib>
18 #include <iostream> 18 #include <iostream>
19 19
20 -class DiscardContents: public QPDFObjectHandle::ParserCallbacks  
21 -{  
22 - public:  
23 - ~DiscardContents() override = default;  
24 - void  
25 - handleObject(QPDFObjectHandle) override  
26 - {  
27 - }  
28 - void  
29 - handleEOF() override  
30 - {  
31 - }  
32 -};  
33 -  
34 class FuzzHelper 20 class FuzzHelper
35 { 21 {
36 public: 22 public:
@@ -92,7 +78,6 @@ FuzzHelper::testPages() @@ -92,7 +78,6 @@ FuzzHelper::testPages()
92 info("generateAppearancesIfNeeded done"); 78 info("generateAppearancesIfNeeded done");
93 pdh.flattenAnnotations(); 79 pdh.flattenAnnotations();
94 info("flattenAnnotations done"); 80 info("flattenAnnotations done");
95 - DiscardContents discard_contents;  
96 int pageno = 0; 81 int pageno = 0;
97 for (auto& page: pdh.getAllPages()) { 82 for (auto& page: pdh.getAllPages()) {
98 ++pageno; 83 ++pageno;
@@ -100,7 +85,7 @@ FuzzHelper::testPages() @@ -100,7 +85,7 @@ FuzzHelper::testPages()
100 info("start page", pageno); 85 info("start page", pageno);
101 page.coalesceContentStreams(); 86 page.coalesceContentStreams();
102 info("coalesceContentStreams done"); 87 info("coalesceContentStreams done");
103 - page.parseContents(&discard_contents); 88 + page.parseContents(nullptr);
104 info("parseContents done"); 89 info("parseContents done");
105 page.getImages(); 90 page.getImages();
106 info("getImages done"); 91 info("getImages done");
libqpdf/QPDFJob.cc
@@ -62,20 +62,6 @@ namespace @@ -62,20 +62,6 @@ namespace
62 std::shared_ptr<Pl_DCT::CompressConfig> config; 62 std::shared_ptr<Pl_DCT::CompressConfig> config;
63 }; 63 };
64 64
65 - class DiscardContents: public QPDFObjectHandle::ParserCallbacks  
66 - {  
67 - public:  
68 - ~DiscardContents() override = default;  
69 - void  
70 - handleObject(QPDFObjectHandle) override  
71 - {  
72 - }  
73 - void  
74 - handleEOF() override  
75 - {  
76 - }  
77 - };  
78 -  
79 struct QPDFPageData 65 struct QPDFPageData
80 { 66 {
81 QPDFPageData(std::string const& filename, QPDF* qpdf, std::string const& range); 67 QPDFPageData(std::string const& filename, QPDF* qpdf, std::string const& range);
@@ -810,12 +796,11 @@ QPDFJob::doCheck(QPDF&amp; pdf) @@ -810,12 +796,11 @@ QPDFJob::doCheck(QPDF&amp; pdf)
810 w.write(); 796 w.write();
811 797
812 // Parse all content streams 798 // Parse all content streams
813 - DiscardContents discard_contents;  
814 int pageno = 0; 799 int pageno = 0;
815 for (auto& page: QPDFPageDocumentHelper(pdf).getAllPages()) { 800 for (auto& page: QPDFPageDocumentHelper(pdf).getAllPages()) {
816 ++pageno; 801 ++pageno;
817 try { 802 try {
818 - page.parseContents(&discard_contents); 803 + page.parseContents(nullptr);
819 } catch (QPDFExc& e) { 804 } catch (QPDFExc& e) {
820 okay = false; 805 okay = false;
821 *m->log->getError() << "ERROR: page " << pageno << ": " << e.what() << "\n"; 806 *m->log->getError() << "ERROR: page " << pageno << ": " << e.what() << "\n";
libqpdf/QPDFObjectHandle.cc
@@ -1549,13 +1549,17 @@ QPDFObjectHandle::parseContentStream_internal( @@ -1549,13 +1549,17 @@ QPDFObjectHandle::parseContentStream_internal(
1549 pl::String buf(stream_data); 1549 pl::String buf(stream_data);
1550 std::string all_description; 1550 std::string all_description;
1551 pipeContentStreams(&buf, description, all_description); 1551 pipeContentStreams(&buf, description, all_description);
1552 - callbacks->contentSize(stream_data.size()); 1552 + if (callbacks) {
  1553 + callbacks->contentSize(stream_data.size());
  1554 + }
1553 try { 1555 try {
1554 parseContentStream_data(stream_data, all_description, callbacks, getOwningQPDF()); 1556 parseContentStream_data(stream_data, all_description, callbacks, getOwningQPDF());
1555 } catch (TerminateParsing&) { 1557 } catch (TerminateParsing&) {
1556 return; 1558 return;
1557 } 1559 }
1558 - callbacks->handleEOF(); 1560 + if (callbacks) {
  1561 + callbacks->handleEOF();
  1562 + }
1559 } 1563 }
1560 1564
1561 void 1565 void
@@ -1583,8 +1587,9 @@ QPDFObjectHandle::parseContentStream_data( @@ -1583,8 +1587,9 @@ QPDFObjectHandle::parseContentStream_data(
1583 break; 1587 break;
1584 } 1588 }
1585 size_t length = QIntC::to_size(input.tell() - offset); 1589 size_t length = QIntC::to_size(input.tell() - offset);
1586 -  
1587 - callbacks->handleObject(obj, QIntC::to_size(offset), length); 1590 + if (callbacks) {
  1591 + callbacks->handleObject(obj, QIntC::to_size(offset), length);
  1592 + }
1588 if (obj.isOperator() && (obj.getOperatorValue() == "ID")) { 1593 if (obj.isOperator() && (obj.getOperatorValue() == "ID")) {
1589 // Discard next character; it is the space after ID that terminated the token. Read 1594 // Discard next character; it is the space after ID that terminated the token. Read
1590 // until end of inline image. 1595 // until end of inline image.
@@ -1606,10 +1611,12 @@ QPDFObjectHandle::parseContentStream_data( @@ -1606,10 +1611,12 @@ QPDFObjectHandle::parseContentStream_data(
1606 "EOF found while reading inline image")); 1611 "EOF found while reading inline image"));
1607 } else { 1612 } else {
1608 QTC::TC("qpdf", "QPDFObjectHandle inline image token"); 1613 QTC::TC("qpdf", "QPDFObjectHandle inline image token");
1609 - callbacks->handleObject(  
1610 - QPDFObjectHandle::newInlineImage(tokenizer.getValue()),  
1611 - QIntC::to_size(offset),  
1612 - length); 1614 + if (callbacks) {
  1615 + callbacks->handleObject(
  1616 + QPDFObjectHandle::newInlineImage(tokenizer.getValue()),
  1617 + QIntC::to_size(offset),
  1618 + length);
  1619 + }
1613 } 1620 }
1614 } 1621 }
1615 } 1622 }