Commit 29e9c34fe344616ec0e9e20bb2f055c7fb80a26d

Authored by Jay Berkenbilt
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.
ChangeLog
  1 +2012-08-11 Jay Berkenbilt <ejb@ql.org>
  2 +
  3 + * Bug fix: let EOF terminate a literal token as well as
  4 + whitespace or comments.
  5 +
1 2012-07-31 Jay Berkenbilt <ejb@ql.org> 6 2012-07-31 Jay Berkenbilt <ejb@ql.org>
2 7
3 * 3.0.0: release 8 * 3.0.0: release
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&lt;InputSource&gt; input, @@ -480,14 +477,22 @@ QPDFTokenizer::readToken(PointerHolder&lt;InputSource&gt; 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