Commit f1800410b6c1f1510890b97fe5e8ce962b69ac94

Authored by m-holger
1 parent efb2e8f6

Revert "Merge pull request #1289 from m-holger/fuzz"

This reverts commit 0e92cf6bf399249c603c3d0212e898fd29e71fcd, reversing
changes made to 7d34b89a69e8e89c098dd373442f7df809c28eff.
fuzz/CMakeLists.txt
@@ -142,9 +142,6 @@ set(CORPUS_OTHER @@ -142,9 +142,6 @@ set(CORPUS_OTHER
142 70306b.fuzz 142 70306b.fuzz
143 71624.fuzz 143 71624.fuzz
144 71689.fuzz 144 71689.fuzz
145 - 99999a.fuzz  
146 - 99999b.fuzz  
147 - 99999c.fuzz  
148 99999d.fuzz 145 99999d.fuzz
149 99999e.fuzz 146 99999e.fuzz
150 369662293.fuzz 147 369662293.fuzz
fuzz/qpdf_extra/99999a.fuzz deleted
1 -%PDF-1.5  
2 -%€€€€  
3 -1 0 obj  
4 -<<  
5 - /Type /Catalog  
6 - /Pages 2 0 R  
7 ->>  
8 -endobj  
9 -2 0 obj  
10 -<<  
11 - /Count 6 Ri  
12 - 0K/ds [3 0 R]  
13 - /Type /Pages  
14 ->>  
15 -endobj  
16 -3 0 obj  
17 -<<  
18 - /Resources <<  
19 - /Font <<  
20 - /F1 5 0 R  
21 - >>  
22 - >>  
23 - /MediaBox [0 0 795 842]  
24 - /Parent 2 0 R  
25 - /Contents 4 0 R  
26 - /Type /Page  
27 -=>  
28 -endobj  
29 -4 0 obj  
30 -<<444444444444444444444444 1 Tr /F1 30 Tf 350 750 Td (foobar) Tj ET  
31 -endstream  
32 -endobj  
33 -5 0 obj  
34 -<<  
35 - /Name /F1  
36 - /BaseFont /Helvetica  
37 - /Type /Font  
38 - /Subtype /Type1  
39 ->>  
40 -e„dobj  
41 -6 0 obj  
42 -<< /Length 6 0 R >>  
43 -stre444444444444444444444444444444<<>>  
44 -endobj  
45 -xref  
46 -0 8  
47 -0000000000 65535 f  
48 -0000000015 00000 n  
49 -0000000066 00000 n  
50 -0000000130 00000 n  
51 -0000000269 00000 n  
52 -0000000362 00000 n  
53 -000000ÎËËÉßÏÏÏ00 n  
54 -0000000500 00000 n  
55 -trailer  
56 -<<  
57 - /Size 713115528178535  
58 - /Root 1 0 R  
59 - /Info 7 0 R  
60 ->>  
61 -startxref  
62 -520  
63 -%%EOF  
64 \ No newline at end of file 0 \ No newline at end of file
fuzz/qpdf_extra/99999b.fuzz deleted
No preview for this file type
fuzz/qpdf_extra/99999c.fuzz deleted
No preview for this file type
fuzz/qtest/fuzz.test
@@ -11,7 +11,7 @@ my $td = new TestDriver(&#39;fuzz&#39;); @@ -11,7 +11,7 @@ my $td = new TestDriver(&#39;fuzz&#39;);
11 11
12 my $qpdf_corpus = $ENV{'QPDF_FUZZ_CORPUS'} || die "must set QPDF_FUZZ_CORPUS"; 12 my $qpdf_corpus = $ENV{'QPDF_FUZZ_CORPUS'} || die "must set QPDF_FUZZ_CORPUS";
13 13
14 -my $n_qpdf_files = 87; # increment when adding new files 14 +my $n_qpdf_files = 84; # increment when adding new files
15 15
16 my @fuzzers = ( 16 my @fuzzers = (
17 ['ascii85' => 1], 17 ['ascii85' => 1],
libqpdf/QPDF.cc
@@ -832,6 +832,10 @@ std::vector&lt;QPDF::Xref_table::Subsection&gt; @@ -832,6 +832,10 @@ std::vector&lt;QPDF::Xref_table::Subsection&gt;
832 QPDF::Xref_table::bad_subsections(std::string& line, qpdf_offset_t start) 832 QPDF::Xref_table::bad_subsections(std::string& line, qpdf_offset_t start)
833 { 833 {
834 std::vector<QPDF::Xref_table::Subsection> result; 834 std::vector<QPDF::Xref_table::Subsection> result;
  835 + qpdf_offset_t f1 = 0;
  836 + int f2 = 0;
  837 + char type = '\0';
  838 +
835 file->seek(start, SEEK_SET); 839 file->seek(start, SEEK_SET);
836 840
837 while (true) { 841 while (true) {
@@ -840,7 +844,7 @@ QPDF::Xref_table::bad_subsections(std::string&amp; line, qpdf_offset_t start) @@ -840,7 +844,7 @@ QPDF::Xref_table::bad_subsections(std::string&amp; line, qpdf_offset_t start)
840 auto [obj, num, offset] = result.emplace_back(subsection(line)); 844 auto [obj, num, offset] = result.emplace_back(subsection(line));
841 file->seek(offset, SEEK_SET); 845 file->seek(offset, SEEK_SET);
842 for (qpdf_offset_t i = obj; i - num < obj; ++i) { 846 for (qpdf_offset_t i = obj; i - num < obj; ++i) {
843 - if (!std::get<0>(read_entry())) { 847 + if (!read_entry(f1, f2, type)) {
844 QTC::TC("qpdf", "QPDF invalid xref entry"); 848 QTC::TC("qpdf", "QPDF invalid xref entry");
845 throw damaged_table("invalid xref entry (obj=" + std::to_string(i) + ")"); 849 throw damaged_table("invalid xref entry (obj=" + std::to_string(i) + ")");
846 } 850 }
@@ -886,13 +890,9 @@ QPDF::Xref_table::subsections(std::string&amp; line) @@ -886,13 +890,9 @@ QPDF::Xref_table::subsections(std::string&amp; line)
886 } 890 }
887 } 891 }
888 892
889 -// Returns (success, f1, f2, type).  
890 -std::tuple<bool, qpdf_offset_t, int, char>  
891 -QPDF::Xref_table::read_bad_entry() 893 +bool
  894 +QPDF::Xref_table::read_bad_entry(qpdf_offset_t& f1, int& f2, char& type)
892 { 895 {
893 - qpdf_offset_t f1{0};  
894 - int f2{0};  
895 - char type{'\0'};  
896 // Reposition after initial read attempt and reread. 896 // Reposition after initial read attempt and reread.
897 file->seek(file->getLastOffset(), SEEK_SET); 897 file->seek(file->getLastOffset(), SEEK_SET);
898 auto line = file->readLine(30); 898 auto line = file->readLine(30);
@@ -910,7 +910,7 @@ QPDF::Xref_table::read_bad_entry() @@ -910,7 +910,7 @@ QPDF::Xref_table::read_bad_entry()
910 } 910 }
911 // Require digit 911 // Require digit
912 if (!QUtil::is_digit(*p)) { 912 if (!QUtil::is_digit(*p)) {
913 - return {false, 0, 0, '\0'}; 913 + return false;
914 } 914 }
915 // Gather digits 915 // Gather digits
916 std::string f1_str; 916 std::string f1_str;
@@ -919,7 +919,7 @@ QPDF::Xref_table::read_bad_entry() @@ -919,7 +919,7 @@ QPDF::Xref_table::read_bad_entry()
919 } 919 }
920 // Require space 920 // Require space
921 if (!QUtil::is_space(*p)) { 921 if (!QUtil::is_space(*p)) {
922 - return {false, 0, 0, '\0'}; 922 + return false;
923 } 923 }
924 if (QUtil::is_space(*(p + 1))) { 924 if (QUtil::is_space(*(p + 1))) {
925 QTC::TC("qpdf", "QPDF ignore first extra space in xref entry"); 925 QTC::TC("qpdf", "QPDF ignore first extra space in xref entry");
@@ -931,7 +931,7 @@ QPDF::Xref_table::read_bad_entry() @@ -931,7 +931,7 @@ QPDF::Xref_table::read_bad_entry()
931 } 931 }
932 // Require digit 932 // Require digit
933 if (!QUtil::is_digit(*p)) { 933 if (!QUtil::is_digit(*p)) {
934 - return {false, 0, 0, '\0'}; 934 + return false;
935 } 935 }
936 // Gather digits 936 // Gather digits
937 std::string f2_str; 937 std::string f2_str;
@@ -940,7 +940,7 @@ QPDF::Xref_table::read_bad_entry() @@ -940,7 +940,7 @@ QPDF::Xref_table::read_bad_entry()
940 } 940 }
941 // Require space 941 // Require space
942 if (!QUtil::is_space(*p)) { 942 if (!QUtil::is_space(*p)) {
943 - return {false, 0, 0, '\0'}; 943 + return false;
944 } 944 }
945 if (QUtil::is_space(*(p + 1))) { 945 if (QUtil::is_space(*(p + 1))) {
946 QTC::TC("qpdf", "QPDF ignore second extra space in xref entry"); 946 QTC::TC("qpdf", "QPDF ignore second extra space in xref entry");
@@ -953,7 +953,7 @@ QPDF::Xref_table::read_bad_entry() @@ -953,7 +953,7 @@ QPDF::Xref_table::read_bad_entry()
953 if ((*p == 'f') || (*p == 'n')) { 953 if ((*p == 'f') || (*p == 'n')) {
954 type = *p; 954 type = *p;
955 } else { 955 } else {
956 - return {false, 0, 0, '\0'}; 956 + return false;
957 } 957 }
958 if ((f1_str.length() != 10) || (f2_str.length() != 5)) { 958 if ((f1_str.length() != 10) || (f2_str.length() != 5)) {
959 QTC::TC("qpdf", "QPDF ignore length error xref entry"); 959 QTC::TC("qpdf", "QPDF ignore length error xref entry");
@@ -967,23 +967,18 @@ QPDF::Xref_table::read_bad_entry() @@ -967,23 +967,18 @@ QPDF::Xref_table::read_bad_entry()
967 f1 = QUtil::string_to_ll(f1_str.c_str()); 967 f1 = QUtil::string_to_ll(f1_str.c_str());
968 f2 = QUtil::string_to_int(f2_str.c_str()); 968 f2 = QUtil::string_to_int(f2_str.c_str());
969 969
970 - return {true, f1, f2, type}; 970 + return true;
971 } 971 }
972 972
973 // Optimistically read and parse xref entry. If entry is bad, call read_bad_xrefEntry and return 973 // Optimistically read and parse xref entry. If entry is bad, call read_bad_xrefEntry and return
974 -// result. Returns (success, f1, f2, type).  
975 -std::tuple<bool, qpdf_offset_t, int, char>  
976 -QPDF::Xref_table::read_entry() 974 +// result.
  975 +bool
  976 +QPDF::Xref_table::read_entry(qpdf_offset_t& f1, int& f2, char& type)
977 { 977 {
978 - qpdf_offset_t f1{0};  
979 - int f2{0};  
980 - char type{'\0'};  
981 std::array<char, 21> line; 978 std::array<char, 21> line;
982 - f1 = 0;  
983 - f2 = 0;  
984 if (file->read(line.data(), 20) != 20) { 979 if (file->read(line.data(), 20) != 20) {
985 // C++20: [[unlikely]] 980 // C++20: [[unlikely]]
986 - return {false, 0, 0, '\0'}; 981 + return false;
987 } 982 }
988 line[20] = '\0'; 983 line[20] = '\0';
989 char const* p = line.data(); 984 char const* p = line.data();
@@ -1007,7 +1002,7 @@ QPDF::Xref_table::read_entry() @@ -1007,7 +1002,7 @@ QPDF::Xref_table::read_entry()
1007 if (!QUtil::is_space(*p++)) { 1002 if (!QUtil::is_space(*p++)) {
1008 // Entry doesn't start with space or digit. 1003 // Entry doesn't start with space or digit.
1009 // C++20: [[unlikely]] 1004 // C++20: [[unlikely]]
1010 - return {false, 0, 0, '\0'}; 1005 + return false;
1011 } 1006 }
1012 // Gather digits. NB No risk of overflow as 99'999 < max int. 1007 // Gather digits. NB No risk of overflow as 99'999 < max int.
1013 while (*p == '0') { 1008 while (*p == '0') {
@@ -1024,10 +1019,10 @@ QPDF::Xref_table::read_entry() @@ -1024,10 +1019,10 @@ QPDF::Xref_table::read_entry()
1024 // No test for valid line[19]. 1019 // No test for valid line[19].
1025 if (*(++p) && *(++p) && (*p == '\n' || *p == '\r') && f1_len == 10 && f2_len == 5) { 1020 if (*(++p) && *(++p) && (*p == '\n' || *p == '\r') && f1_len == 10 && f2_len == 5) {
1026 // C++20: [[likely]] 1021 // C++20: [[likely]]
1027 - return {true, f1, f2, type}; 1022 + return true;
1028 } 1023 }
1029 } 1024 }
1030 - return read_bad_entry(); 1025 + return read_bad_entry(f1, f2, type);
1031 } 1026 }
1032 1027
1033 // Read a single cross-reference table section and associated trailer. 1028 // Read a single cross-reference table section and associated trailer.
@@ -1057,10 +1052,7 @@ QPDF::Xref_table::process_section(qpdf_offset_t xref_offset) @@ -1057,10 +1052,7 @@ QPDF::Xref_table::process_section(qpdf_offset_t xref_offset)
1057 QTC::TC("qpdf", "QPDF trailer size not integer"); 1052 QTC::TC("qpdf", "QPDF trailer size not integer");
1058 throw qpdf.damagedPDF("trailer", "/Size key in trailer dictionary is not an integer"); 1053 throw qpdf.damagedPDF("trailer", "/Size key in trailer dictionary is not an integer");
1059 } 1054 }
1060 - if (sz >= static_cast<unsigned int>(max_id_)) {  
1061 - QTC::TC("qpdf", "QPDF trailer size impossibly large");  
1062 - throw qpdf.damagedPDF("trailer", "/Size key in trailer dictionary is impossibly large");  
1063 - } 1055 +
1064 table.resize(sz); 1056 table.resize(sz);
1065 } 1057 }
1066 1058
@@ -1072,8 +1064,10 @@ QPDF::Xref_table::process_section(qpdf_offset_t xref_offset) @@ -1072,8 +1064,10 @@ QPDF::Xref_table::process_section(qpdf_offset_t xref_offset)
1072 first_item_offset_ = file->tell(); 1064 first_item_offset_ = file->tell();
1073 } 1065 }
1074 // For xref_table, these will always be small enough to be ints 1066 // For xref_table, these will always be small enough to be ints
1075 - auto [success, f1, f2, type] = read_entry();  
1076 - if (!success) { 1067 + qpdf_offset_t f1 = 0;
  1068 + int f2 = 0;
  1069 + char type = '\0';
  1070 + if (!read_entry(f1, f2, type)) {
1077 throw damaged_table("invalid xref entry (obj=" + std::to_string(i) + ")"); 1071 throw damaged_table("invalid xref entry (obj=" + std::to_string(i) + ")");
1078 } 1072 }
1079 if (type == 'f') { 1073 if (type == 'f') {
@@ -1594,7 +1588,8 @@ QPDF::Xref_table::read_trailer() @@ -1594,7 +1588,8 @@ QPDF::Xref_table::read_trailer()
1594 { 1588 {
1595 qpdf_offset_t offset = file->tell(); 1589 qpdf_offset_t offset = file->tell();
1596 bool empty = false; 1590 bool empty = false;
1597 - auto object = QPDFParser(*file, "trailer", tokenizer, nullptr, &qpdf, true).parse(empty, false); 1591 + auto object =
  1592 + QPDFParser(*file, "trailer", tokenizer, nullptr, &qpdf, true).parse(empty, false);
1598 if (empty) { 1593 if (empty) {
1599 // Nothing in the PDF spec appears to allow empty objects, but they have been encountered in 1594 // Nothing in the PDF spec appears to allow empty objects, but they have been encountered in
1600 // actual PDF files and Adobe Reader appears to ignore them. 1595 // actual PDF files and Adobe Reader appears to ignore them.
libqpdf/qpdf/QPDF_private.hh
@@ -292,8 +292,8 @@ class QPDF::Xref_table @@ -292,8 +292,8 @@ class QPDF::Xref_table
292 std::vector<Subsection> subsections(std::string& line); 292 std::vector<Subsection> subsections(std::string& line);
293 std::vector<Subsection> bad_subsections(std::string& line, qpdf_offset_t offset); 293 std::vector<Subsection> bad_subsections(std::string& line, qpdf_offset_t offset);
294 Subsection subsection(std::string const& line); 294 Subsection subsection(std::string const& line);
295 - std::tuple<bool, qpdf_offset_t, int, char> read_entry();  
296 - std::tuple<bool, qpdf_offset_t, int, char> read_bad_entry(); 295 + bool read_entry(qpdf_offset_t& f1, int& f2, char& type);
  296 + bool read_bad_entry(qpdf_offset_t& f1, int& f2, char& type);
297 297
298 // Methods to parse streams 298 // Methods to parse streams
299 qpdf_offset_t read_stream(qpdf_offset_t offset); 299 qpdf_offset_t read_stream(qpdf_offset_t offset);
qpdf/qpdf.testcov
@@ -55,7 +55,6 @@ QPDF invalid xref entry 0 @@ -55,7 +55,6 @@ QPDF invalid xref entry 0
55 QPDF missing trailer 0 55 QPDF missing trailer 0
56 QPDF trailer lacks size 0 56 QPDF trailer lacks size 0
57 QPDF trailer size not integer 0 57 QPDF trailer size not integer 0
58 -QPDF trailer size impossibly large 0  
59 QPDF trailer prev not integer 0 58 QPDF trailer prev not integer 0
60 QPDFParser bad brace 0 59 QPDFParser bad brace 0
61 QPDFParser bad brace in parseRemainder 0 60 QPDFParser bad brace in parseRemainder 0
qpdf/qtest/qpdf/issue-fuzz.out deleted
1 -WARNING: issue-fuzz.pdf: can't find PDF header  
2 -WARNING: issue-fuzz.pdf (xref table, offset 19): accepting invalid xref table entry  
3 -WARNING: issue-fuzz.pdf (trailer, offset 36): unknown token while reading object; treating as string  
4 -WARNING: issue-fuzz.pdf (trailer, offset 53): unexpected >  
5 -WARNING: issue-fuzz.pdf (trailer, offset 54): unknown token while reading object; treating as string  
6 -WARNING: issue-fuzz.pdf (trailer, offset 58): unknown token while reading object; treating as string  
7 -WARNING: issue-fuzz.pdf (trailer, offset 72): unknown token while reading object; treating as string  
8 -WARNING: issue-fuzz.pdf (trailer, offset 36): dictionary ended prematurely; using null as value for last key  
9 -WARNING: issue-fuzz.pdf (trailer, offset 36): expected dictionary key but found non-name object; inserting key /QPDFFake1  
10 -WARNING: issue-fuzz.pdf (trailer, offset 36): expected dictionary key but found non-name object; inserting key /QPDFFake2  
11 -WARNING: issue-fuzz.pdf (trailer, offset 36): expected dictionary key but found non-name object; inserting key /QPDFFake3  
12 -WARNING: issue-fuzz.pdf (trailer, offset 36): expected dictionary key but found non-name object; inserting key /QPDFFake4  
13 -WARNING: issue-fuzz.pdf (trailer, offset 36): expected dictionary key but found non-name object; inserting key /QPDFFake5  
14 -WARNING: issue-fuzz.pdf (trailer, offset 36): expected dictionary key but found non-name object; inserting key /QPDFFake6  
15 -WARNING: issue-fuzz.pdf (trailer, offset 36): expected dictionary key but found non-name object; inserting key /QPDFFake7  
16 -WARNING: issue-fuzz.pdf: file is damaged  
17 -WARNING: issue-fuzz.pdf (trailer, offset 32): /Size key in trailer dictionary is impossibly large  
18 -WARNING: issue-fuzz.pdf: Attempting to reconstruct cross-reference table  
19 -qpdf: issue-fuzz.pdf: unable to find /Root dictionary  
qpdf/qtest/qpdf/issue-fuzz.pdf deleted
No preview for this file type
qpdf/qtest/specific-bugs.test
@@ -38,7 +38,6 @@ my @bug_tests = ( @@ -38,7 +38,6 @@ my @bug_tests = (
38 ["263", "empty xref stream", 2], 38 ["263", "empty xref stream", 2],
39 ["335a", "ozz-fuzz-12152", 2], 39 ["335a", "ozz-fuzz-12152", 2],
40 ["335b", "ozz-fuzz-14845", 2], 40 ["335b", "ozz-fuzz-14845", 2],
41 - ["fuzz", "impossibly large trailer /Size"],  
42 # ["fuzz-16214", "stream in object stream", 3, "--preserve-unreferenced"], 41 # ["fuzz-16214", "stream in object stream", 3, "--preserve-unreferenced"],
43 # When adding to this list, consider adding to CORPUS_FROM_TEST in 42 # When adding to this list, consider adding to CORPUS_FROM_TEST in
44 # fuzz/CMakeLists.txt and updating the count in 43 # fuzz/CMakeLists.txt and updating the count in