Commit 29e9c34fe344616ec0e9e20bb2f055c7fb80a26d
1 parent
137dc7ac
Bug fix: let EOF resolve literal token
Previously only whitespace and comments did it. This fix is needed for object streams whose last object is a literal (name, integer, real, string) not terminated by space or newline.
Showing
3 changed files
with
27 additions
and
15 deletions
ChangeLog
libqpdf/QPDFTokenizer.cc
| @@ -434,22 +434,19 @@ QPDFTokenizer::presentCharacter(char ch) | @@ -434,22 +434,19 @@ QPDFTokenizer::presentCharacter(char ch) | ||
| 434 | void | 434 | void |
| 435 | QPDFTokenizer::presentEOF() | 435 | QPDFTokenizer::presentEOF() |
| 436 | { | 436 | { |
| 437 | - switch (state) | 437 | + if (state == st_literal) |
| 438 | { | 438 | { |
| 439 | - case st_token_ready: | ||
| 440 | - case st_top: | ||
| 441 | - // okay | ||
| 442 | - break; | ||
| 443 | - | ||
| 444 | - case st_in_comment: | ||
| 445 | - state = st_top; | ||
| 446 | - break; | ||
| 447 | - | ||
| 448 | - default: | 439 | + QTC::TC("qpdf", "QPDF_Tokenizer EOF reading appendable token"); |
| 440 | + resolveLiteral(); | ||
| 441 | + } | ||
| 442 | + else if (state != st_token_ready) | ||
| 443 | + { | ||
| 444 | + QTC::TC("qpdf", "QPDF_Tokenizer EOF reading token"); | ||
| 449 | type = tt_bad; | 445 | type = tt_bad; |
| 450 | error_message = "EOF while reading token"; | 446 | error_message = "EOF while reading token"; |
| 451 | - state = st_token_ready; | ||
| 452 | } | 447 | } |
| 448 | + | ||
| 449 | + state = st_token_ready; | ||
| 453 | } | 450 | } |
| 454 | 451 | ||
| 455 | bool | 452 | bool |
| @@ -480,14 +477,22 @@ QPDFTokenizer::readToken(PointerHolder<InputSource> input, | @@ -480,14 +477,22 @@ QPDFTokenizer::readToken(PointerHolder<InputSource> input, | ||
| 480 | Token token; | 477 | Token token; |
| 481 | bool unread_char; | 478 | bool unread_char; |
| 482 | char char_to_unread; | 479 | char char_to_unread; |
| 480 | + bool presented_eof = false; | ||
| 483 | while (! getToken(token, unread_char, char_to_unread)) | 481 | while (! getToken(token, unread_char, char_to_unread)) |
| 484 | { | 482 | { |
| 485 | char ch; | 483 | char ch; |
| 486 | if (input->read(&ch, 1) == 0) | 484 | if (input->read(&ch, 1) == 0) |
| 487 | { | 485 | { |
| 488 | - throw QPDFExc(qpdf_e_damaged_pdf, input->getName(), | ||
| 489 | - context, offset, | ||
| 490 | - "EOF while reading token"); | 486 | + if (! presented_eof) |
| 487 | + { | ||
| 488 | + presentEOF(); | ||
| 489 | + presented_eof = true; | ||
| 490 | + } | ||
| 491 | + else | ||
| 492 | + { | ||
| 493 | + throw std::logic_error( | ||
| 494 | + "getToken returned false after presenting EOF"); | ||
| 495 | + } | ||
| 491 | } | 496 | } |
| 492 | else | 497 | else |
| 493 | { | 498 | { |
qpdf/qpdf.testcov
| @@ -238,3 +238,5 @@ QPDFWriter copy use_aes 1 | @@ -238,3 +238,5 @@ QPDFWriter copy use_aes 1 | ||
| 238 | QPDFObjectHandle indirect without context 0 | 238 | QPDFObjectHandle indirect without context 0 |
| 239 | QPDFObjectHandle trailing data in parse 0 | 239 | QPDFObjectHandle trailing data in parse 0 |
| 240 | qpdf pages encryption password 0 | 240 | qpdf pages encryption password 0 |
| 241 | +QPDF_Tokenizer EOF reading token 0 | ||
| 242 | +QPDF_Tokenizer EOF reading appendable token 0 |