Commit 27791cc891c51b09386eae3e44db784dc4b72a3b

Authored by m-holger
1 parent 791faac4

Refactor QPDF::isLinearized

libqpdf/QPDF.cc
@@ -2764,7 +2764,8 @@ QPDF::pipeStreamData( @@ -2764,7 +2764,8 @@ QPDF::pipeStreamData(
2764 try { 2764 try {
2765 auto buf = file->read(length, offset); 2765 auto buf = file->read(length, offset);
2766 if (buf.size() != length) { 2766 if (buf.size() != length) {
2767 - throw damagedPDF(*file, "", offset + toO(buf.size()), "unexpected EOF reading stream data"); 2767 + throw damagedPDF(
  2768 + *file, "", offset + toO(buf.size()), "unexpected EOF reading stream data");
2768 } 2769 }
2769 pipeline->write(buf.data(), length); 2770 pipeline->write(buf.data(), length);
2770 attempted_finish = true; 2771 attempted_finish = true;
libqpdf/QPDF_linearization.cc
@@ -20,6 +20,7 @@ @@ -20,6 +20,7 @@
20 #include <cstring> 20 #include <cstring>
21 21
22 using namespace qpdf; 22 using namespace qpdf;
  23 +using namespace std::literals;
23 24
24 template <class T, class int_type> 25 template <class T, class int_type>
25 static void 26 static void
@@ -97,26 +98,18 @@ QPDF::isLinearized() @@ -97,26 +98,18 @@ QPDF::isLinearized()
97 98
98 // The PDF spec says the linearization dictionary must be completely contained within the first 99 // The PDF spec says the linearization dictionary must be completely contained within the first
99 // 1024 bytes of the file. Add a byte for a null terminator. 100 // 1024 bytes of the file. Add a byte for a null terminator.
100 - auto buffer = m->file->read(1024, 0);  
101 -  
102 - auto buf = buffer.data();  
103 - auto tbuf_size = buffer.size(); 101 + auto buffer = m->file->read(1024, 0);
104 int lindict_obj = -1; 102 int lindict_obj = -1;
105 - char* p = buf; 103 + size_t pos = 0;
106 while (lindict_obj == -1) { 104 while (lindict_obj == -1) {
107 // Find a digit or end of buffer 105 // Find a digit or end of buffer
108 - while (((p - buf) < tbuf_size) && (!util::is_digit(*p))) {  
109 - ++p;  
110 - }  
111 - if (p - buf == tbuf_size) {  
112 - break; 106 + pos = buffer.find_first_of("0123456789"sv, pos);
  107 + if (pos == std::string::npos) {
  108 + return false;
113 } 109 }
114 // Seek to the digit. Then skip over digits for a potential 110 // Seek to the digit. Then skip over digits for a potential
115 // next iteration. 111 // next iteration.
116 - m->file->seek(p - buf, SEEK_SET);  
117 - while (((p - buf) < tbuf_size) && util::is_digit(*p)) {  
118 - ++p;  
119 - } 112 + m->file->seek(toO(pos), SEEK_SET);
120 113
121 QPDFTokenizer::Token t1 = readToken(*m->file); 114 QPDFTokenizer::Token t1 = readToken(*m->file);
122 if (t1.isInteger() && readToken(*m->file).isInteger() && 115 if (t1.isInteger() && readToken(*m->file).isInteger() &&
@@ -124,13 +117,17 @@ QPDF::isLinearized() @@ -124,13 +117,17 @@ QPDF::isLinearized()
124 readToken(*m->file).getType() == QPDFTokenizer::tt_dict_open) { 117 readToken(*m->file).getType() == QPDFTokenizer::tt_dict_open) {
125 lindict_obj = toI(QUtil::string_to_ll(t1.getValue().c_str())); 118 lindict_obj = toI(QUtil::string_to_ll(t1.getValue().c_str()));
126 } 119 }
  120 + pos = buffer.find_first_not_of("0123456789"sv, pos);
  121 + if (pos == std::string::npos) {
  122 + return false;
  123 + }
127 } 124 }
128 125
129 if (lindict_obj <= 0) { 126 if (lindict_obj <= 0) {
130 return false; 127 return false;
131 } 128 }
132 129
133 - auto candidate = getObjectByID(lindict_obj, 0); 130 + auto candidate = getObject(lindict_obj, 0);
134 if (!candidate.isDictionary()) { 131 if (!candidate.isDictionary()) {
135 return false; 132 return false;
136 } 133 }
@@ -545,7 +542,7 @@ QPDF::maxEnd(ObjUser const&amp; ou) @@ -545,7 +542,7 @@ QPDF::maxEnd(ObjUser const&amp; ou)
545 } 542 }
546 qpdf_offset_t end = 0; 543 qpdf_offset_t end = 0;
547 for (auto const& og: m->obj_user_to_objects[ou]) { 544 for (auto const& og: m->obj_user_to_objects[ou]) {
548 - if (m->obj_cache.count(og) == 0) { 545 + if (!m->obj_cache.count(og)) {
549 stopOnError("unknown object referenced in object user table"); 546 stopOnError("unknown object referenced in object user table");
550 } 547 }
551 end = std::max(end, m->obj_cache[og].end_after_space); 548 end = std::max(end, m->obj_cache[og].end_after_space);