2
1
mirror of https://github.com/qpdf/qpdf.git synced 2025-01-02 22:50:20 +00:00

Merge pull request #1271 from m-holger/rsl

Fix QPDF::recoverStreamLength
This commit is contained in:
m-holger 2024-09-16 20:38:14 +01:00 committed by GitHub
commit 54ac92eb1d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 121 additions and 17 deletions

View File

@ -3,7 +3,7 @@
<RiderCodeStyleSettings> <RiderCodeStyleSettings>
<option name="/Default/CodeStyle/CodeFormatting/CppClangFormat/EnableClangFormatSupport/@EntryValue" value="true" type="bool" /> <option name="/Default/CodeStyle/CodeFormatting/CppClangFormat/EnableClangFormatSupport/@EntryValue" value="true" type="bool" />
</RiderCodeStyleSettings> </RiderCodeStyleSettings>
<SqlCodeStyleSettings version="7"> <SqlCodeStyleSettings version="6">
<option name="KEYWORD_CASE" value="2" /> <option name="KEYWORD_CASE" value="2" />
</SqlCodeStyleSettings> </SqlCodeStyleSettings>
<clangFormatSettings> <clangFormatSettings>

View File

@ -1649,26 +1649,28 @@ QPDF::recoverStreamLength(
} }
if (length) { if (length) {
qpdf_offset_t this_obj_offset = 0; auto end = stream_offset + toO(length);
QPDFObjGen this_og; qpdf_offset_t found_offset = 0;
QPDFObjGen found_og;
// Make sure this is inside this object // Make sure this is inside this object
for (auto const& iter: m->xref_table) { for (auto const& [current_og, entry]: m->xref_table) {
QPDFXRefEntry const& entry = iter.second;
if (entry.getType() == 1) { if (entry.getType() == 1) {
qpdf_offset_t obj_offset = entry.getOffset(); qpdf_offset_t obj_offset = entry.getOffset();
if ((obj_offset > stream_offset) && if (found_offset < obj_offset && obj_offset < end) {
((this_obj_offset == 0) || (this_obj_offset > obj_offset))) { found_offset = obj_offset;
this_obj_offset = obj_offset; found_og = current_og;
this_og = iter.first;
} }
} }
} }
if (this_obj_offset && (this_og == og)) { if (!found_offset || found_og == og) {
// Well, we found endstream\nendobj within the space allowed for this object, so we're // If we are trying to recover an XRef stream the xref table will not contain and
// probably in good shape. // won't contain any entries, therefore we cannot check the found length. Otherwise we
// found endstream\nendobj within the space allowed for this object, so we're probably
// in good shape.
} else { } else {
QTC::TC("qpdf", "QPDF found wrong endstream in recovery"); QTC::TC("qpdf", "QPDF found wrong endstream in recovery");
length = 0;
} }
} }

View File

@ -55,6 +55,7 @@ my @badfiles = ("not a PDF file", # 1
"bad dictionary key", # 36 "bad dictionary key", # 36
"space before xref", # 37 "space before xref", # 37
"startxref to space then eof", # 38 "startxref to space then eof", # 38
"stream lenth revocery overlapping", # 39
); );
$n_tests += @badfiles + 8; $n_tests += @badfiles + 8;
@ -65,7 +66,7 @@ $n_tests += @badfiles + 8;
# have error conditions that used to be fatal but are now considered # have error conditions that used to be fatal but are now considered
# non-fatal. # non-fatal.
my %badtest_overrides = (); my %badtest_overrides = ();
for(6, 12..15, 17, 18..32, 34..37) for(6, 12..15, 17, 18..32, 34..37, 39)
{ {
$badtest_overrides{$_} = 0; $badtest_overrides{$_} = 0;
} }

View File

@ -17,7 +17,7 @@ my $td = new TestDriver('parsing');
my $n_tests = 17; my $n_tests = 17;
$td->runtest("parse objects from string", $td->runtest("parse objects from string",
{$td->COMMAND => "test_driver 31 bad39.qdf"}, {$td->COMMAND => "test_driver 31 bad-parse.qdf"},
{$td->FILE => "parse-object.out", $td->EXIT_STATUS => 0}, {$td->FILE => "parse-object.out", $td->EXIT_STATUS => 0},
$td->NORMALIZE_NEWLINES); $td->NORMALIZE_NEWLINES);
$td->runtest("EOF terminating literal tokens", $td->runtest("EOF terminating literal tokens",

View File

@ -0,0 +1,13 @@
WARNING: bad39.pdf (object 4 0, offset 385): expected endstream
WARNING: bad39.pdf (object 4 0, offset 341): attempting to recover stream length
WARNING: bad39.pdf (object 4 0, offset 341): unable to recover stream data; treating stream as empty
/QTest is indirect and has type stream (10)
/QTest is a stream. Dictionary: << /Length 44 >>
Raw stream data:
Uncompressed stream data:
End of stream data
unparse: 4 0 R
unparseResolved: 4 0 R
test 1 done

View File

@ -0,0 +1,7 @@
WARNING: bad39.pdf (object 4 0, offset 385): expected endstream
/QTest is implicit
/QTest is indirect and has type null (2)
/QTest is null
unparse: 4 0 R
unparseResolved: null
test 0 done

81
qpdf/qtest/qpdf/bad39.pdf Normal file
View File

@ -0,0 +1,81 @@
%PDF-1.3
1 0 obj
<<
/Type /Catalog
/Pages 2 0 R
>>
endobj
2 0 obj
<<
/Type /Pages
/Kids [
3 0 R
]
/Count 1
>>
endobj
3 0 obj
<<
/Type /Page
/Parent 2 0 R
/MediaBox [0 0 612 792]
/Contents 4 0 R
/Resources <<
/ProcSet 5 0 R
/Font <<
/F1 6 0 R
>>
>>
>>
endobj
4 0 obj
<<
/Length 44
>>
stream
BT
/F1 24 Tf
72 720 Td
(Potato) Tj
ET
enxstream
enxobj
5 0 obj
[
/PDF
/Text
]
endobj
6 0 obj
<<
/Type /Font
/Subtype /Type1
/Name /F1
/BaseFont /Helvetica
/Encoding /Winng
>>
endstream
endobj
xref
0 7
0000000000 65535 f
0000000009 00000 n
0000000063 00000 n
0000000135 00000 n
0000000307 00000 n
0000000403 00000 n
0000000438 00000 n
trailer <<
/Size 7
/Root 1 0 R
/QTest 4 0 R
>>
startxref
556
%%EOF

View File

@ -5,7 +5,7 @@ WARNING: parsed object (offset 9): unknown token while reading object; treating
WARNING: parsed object: treating unexpected brace token as null WARNING: parsed object: treating unexpected brace token as null
WARNING: parsed object: treating unexpected brace token as null WARNING: parsed object: treating unexpected brace token as null
WARNING: parsed object: unexpected dictionary close token WARNING: parsed object: unexpected dictionary close token
WARNING: bad39.qdf (object 7 0, offset 1121): unexpected EOF WARNING: bad-parse.qdf (object 7 0, offset 1121): unexpected EOF
WARNING: bad39.qdf (object 7 0, offset 1121): expected endobj WARNING: bad-parse.qdf (object 7 0, offset 1121): expected endobj
WARNING: bad39.qdf (object 7 0, offset 1121): EOF after endobj WARNING: bad-parse.qdf (object 7 0, offset 1121): EOF after endobj
test 31 done test 31 done