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 142 70306b.fuzz
143 143 71624.fuzz
144 144 71689.fuzz
145   - 99999a.fuzz
146   - 99999b.fuzz
147   - 99999c.fuzz
148 145 99999d.fuzz
149 146 99999e.fuzz
150 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 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 11  
12 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 16 my @fuzzers = (
17 17 ['ascii85' => 1],
... ...
libqpdf/QPDF.cc
... ... @@ -832,6 +832,10 @@ std::vector&lt;QPDF::Xref_table::Subsection&gt;
832 832 QPDF::Xref_table::bad_subsections(std::string& line, qpdf_offset_t start)
833 833 {
834 834 std::vector<QPDF::Xref_table::Subsection> result;
  835 + qpdf_offset_t f1 = 0;
  836 + int f2 = 0;
  837 + char type = '\0';
  838 +
835 839 file->seek(start, SEEK_SET);
836 840  
837 841 while (true) {
... ... @@ -840,7 +844,7 @@ QPDF::Xref_table::bad_subsections(std::string&amp; line, qpdf_offset_t start)
840 844 auto [obj, num, offset] = result.emplace_back(subsection(line));
841 845 file->seek(offset, SEEK_SET);
842 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 848 QTC::TC("qpdf", "QPDF invalid xref entry");
845 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 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 896 // Reposition after initial read attempt and reread.
897 897 file->seek(file->getLastOffset(), SEEK_SET);
898 898 auto line = file->readLine(30);
... ... @@ -910,7 +910,7 @@ QPDF::Xref_table::read_bad_entry()
910 910 }
911 911 // Require digit
912 912 if (!QUtil::is_digit(*p)) {
913   - return {false, 0, 0, '\0'};
  913 + return false;
914 914 }
915 915 // Gather digits
916 916 std::string f1_str;
... ... @@ -919,7 +919,7 @@ QPDF::Xref_table::read_bad_entry()
919 919 }
920 920 // Require space
921 921 if (!QUtil::is_space(*p)) {
922   - return {false, 0, 0, '\0'};
  922 + return false;
923 923 }
924 924 if (QUtil::is_space(*(p + 1))) {
925 925 QTC::TC("qpdf", "QPDF ignore first extra space in xref entry");
... ... @@ -931,7 +931,7 @@ QPDF::Xref_table::read_bad_entry()
931 931 }
932 932 // Require digit
933 933 if (!QUtil::is_digit(*p)) {
934   - return {false, 0, 0, '\0'};
  934 + return false;
935 935 }
936 936 // Gather digits
937 937 std::string f2_str;
... ... @@ -940,7 +940,7 @@ QPDF::Xref_table::read_bad_entry()
940 940 }
941 941 // Require space
942 942 if (!QUtil::is_space(*p)) {
943   - return {false, 0, 0, '\0'};
  943 + return false;
944 944 }
945 945 if (QUtil::is_space(*(p + 1))) {
946 946 QTC::TC("qpdf", "QPDF ignore second extra space in xref entry");
... ... @@ -953,7 +953,7 @@ QPDF::Xref_table::read_bad_entry()
953 953 if ((*p == 'f') || (*p == 'n')) {
954 954 type = *p;
955 955 } else {
956   - return {false, 0, 0, '\0'};
  956 + return false;
957 957 }
958 958 if ((f1_str.length() != 10) || (f2_str.length() != 5)) {
959 959 QTC::TC("qpdf", "QPDF ignore length error xref entry");
... ... @@ -967,23 +967,18 @@ QPDF::Xref_table::read_bad_entry()
967 967 f1 = QUtil::string_to_ll(f1_str.c_str());
968 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 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 978 std::array<char, 21> line;
982   - f1 = 0;
983   - f2 = 0;
984 979 if (file->read(line.data(), 20) != 20) {
985 980 // C++20: [[unlikely]]
986   - return {false, 0, 0, '\0'};
  981 + return false;
987 982 }
988 983 line[20] = '\0';
989 984 char const* p = line.data();
... ... @@ -1007,7 +1002,7 @@ QPDF::Xref_table::read_entry()
1007 1002 if (!QUtil::is_space(*p++)) {
1008 1003 // Entry doesn't start with space or digit.
1009 1004 // C++20: [[unlikely]]
1010   - return {false, 0, 0, '\0'};
  1005 + return false;
1011 1006 }
1012 1007 // Gather digits. NB No risk of overflow as 99'999 < max int.
1013 1008 while (*p == '0') {
... ... @@ -1024,10 +1019,10 @@ QPDF::Xref_table::read_entry()
1024 1019 // No test for valid line[19].
1025 1020 if (*(++p) && *(++p) && (*p == '\n' || *p == '\r') && f1_len == 10 && f2_len == 5) {
1026 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 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 1052 QTC::TC("qpdf", "QPDF trailer size not integer");
1058 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 1056 table.resize(sz);
1065 1057 }
1066 1058  
... ... @@ -1072,8 +1064,10 @@ QPDF::Xref_table::process_section(qpdf_offset_t xref_offset)
1072 1064 first_item_offset_ = file->tell();
1073 1065 }
1074 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 1071 throw damaged_table("invalid xref entry (obj=" + std::to_string(i) + ")");
1078 1072 }
1079 1073 if (type == 'f') {
... ... @@ -1594,7 +1588,8 @@ QPDF::Xref_table::read_trailer()
1594 1588 {
1595 1589 qpdf_offset_t offset = file->tell();
1596 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 1593 if (empty) {
1599 1594 // Nothing in the PDF spec appears to allow empty objects, but they have been encountered in
1600 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 292 std::vector<Subsection> subsections(std::string& line);
293 293 std::vector<Subsection> bad_subsections(std::string& line, qpdf_offset_t offset);
294 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 298 // Methods to parse streams
299 299 qpdf_offset_t read_stream(qpdf_offset_t offset);
... ...
qpdf/qpdf.testcov
... ... @@ -55,7 +55,6 @@ QPDF invalid xref entry 0
55 55 QPDF missing trailer 0
56 56 QPDF trailer lacks size 0
57 57 QPDF trailer size not integer 0
58   -QPDF trailer size impossibly large 0
59 58 QPDF trailer prev not integer 0
60 59 QPDFParser bad brace 0
61 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 38 ["263", "empty xref stream", 2],
39 39 ["335a", "ozz-fuzz-12152", 2],
40 40 ["335b", "ozz-fuzz-14845", 2],
41   - ["fuzz", "impossibly large trailer /Size"],
42 41 # ["fuzz-16214", "stream in object stream", 3, "--preserve-unreferenced"],
43 42 # When adding to this list, consider adding to CORPUS_FROM_TEST in
44 43 # fuzz/CMakeLists.txt and updating the count in
... ...