Commit 3082e4e6066dde405e4f01edec4518fd9f2c3fc7

Authored by Jay Berkenbilt
1 parent 90840be5

Find xref without PCRE

libqpdf/QPDF.cc
@@ -477,15 +477,21 @@ QPDF::read_xref(qpdf_offset_t xref_offset) @@ -477,15 +477,21 @@ QPDF::read_xref(qpdf_offset_t xref_offset)
477 // The PDF spec says xref must be followed by a line 477 // The PDF spec says xref must be followed by a line
478 // terminator, but files exist in the wild where it is 478 // terminator, but files exist in the wild where it is
479 // terminated by arbitrary whitespace. 479 // terminated by arbitrary whitespace.
480 - PCRE xref_re("^xref\\s+");  
481 - PCRE::Match m = xref_re.match(buf);  
482 - if (m) 480 + if ((strncmp(buf, "xref", 4) == 0) &&
  481 + QUtil::is_space(buf[4]))
483 { 482 {
484 QTC::TC("qpdf", "QPDF xref space", 483 QTC::TC("qpdf", "QPDF xref space",
485 ((buf[4] == '\n') ? 0 : 484 ((buf[4] == '\n') ? 0 :
486 (buf[4] == '\r') ? 1 : 485 (buf[4] == '\r') ? 1 :
487 (buf[4] == ' ') ? 2 : 9999)); 486 (buf[4] == ' ') ? 2 : 9999));
488 - xref_offset = read_xrefTable(xref_offset + m.getMatch(0).length()); 487 + int skip = 4;
  488 + // buf is null-terminated, and QUtil::is_space('\0') is
  489 + // false, so this won't overrun.
  490 + while (QUtil::is_space(buf[skip]))
  491 + {
  492 + ++skip;
  493 + }
  494 + xref_offset = read_xrefTable(xref_offset + skip);
489 } 495 }
490 else 496 else
491 { 497 {
libqpdf/QUtil.cc
@@ -511,13 +511,13 @@ QUtil::srandom(unsigned int seed) @@ -511,13 +511,13 @@ QUtil::srandom(unsigned int seed)
511 bool 511 bool
512 QUtil::is_hex_digit(char ch) 512 QUtil::is_hex_digit(char ch)
513 { 513 {
514 - return (strchr("0123456789abcdefABCDEF", ch) != 0); 514 + return (ch && (strchr("0123456789abcdefABCDEF", ch) != 0));
515 } 515 }
516 516
517 bool 517 bool
518 QUtil::is_space(char ch) 518 QUtil::is_space(char ch)
519 { 519 {
520 - return (strchr(" \f\n\r\t\v", ch) != 0); 520 + return (ch && (strchr(" \f\n\r\t\v", ch) != 0));
521 } 521 }
522 522
523 bool 523 bool
qpdf/qtest/qpdf/issue-101.out
@@ -10,7 +10,7 @@ WARNING: issue-101.pdf (trailer, file position 2026): /Length key in stream dict @@ -10,7 +10,7 @@ WARNING: issue-101.pdf (trailer, file position 2026): /Length key in stream dict
10 WARNING: issue-101.pdf (trailer, file position 2097): attempting to recover stream length 10 WARNING: issue-101.pdf (trailer, file position 2097): attempting to recover stream length
11 WARNING: issue-101.pdf (trailer, file position 2097): recovered stream length: 709 11 WARNING: issue-101.pdf (trailer, file position 2097): recovered stream length: 709
12 WARNING: issue-101.pdf (trailer, file position 2928): unknown token while reading object; treating as string 12 WARNING: issue-101.pdf (trailer, file position 2928): unknown token while reading object; treating as string
13 -WARNING: issue-101.pdf (trailer, file position 2930): unknown token while reading object; treating as string 13 +WARNING: issue-101.pdf (trailer, file position 2929): unknown token while reading object; treating as string
14 WARNING: issue-101.pdf (trailer, file position 2928): expected dictionary key but found non-name object; inserting key /QPDFFake1 14 WARNING: issue-101.pdf (trailer, file position 2928): expected dictionary key but found non-name object; inserting key /QPDFFake1
15 WARNING: issue-101.pdf (trailer, file position 2928): expected dictionary key but found non-name object; inserting key /QPDFFake2 15 WARNING: issue-101.pdf (trailer, file position 2928): expected dictionary key but found non-name object; inserting key /QPDFFake2
16 WARNING: issue-101.pdf (trailer, file position 2928): expected dictionary key but found non-name object; inserting key /QPDFFake3 16 WARNING: issue-101.pdf (trailer, file position 2928): expected dictionary key but found non-name object; inserting key /QPDFFake3