commit a1014f81d804955bb38b434865b733271aa3d7a7 from: Sven M. Hallberg date: Thu Mar 30 16:52:28 2023 UTC improve handling of parse errors in xref stream data Improve on the bugfix in commit a5abf1e2: - Reinstate the assert for 'res->ast != NULL'. If it fails, there is a bug in the parser, not an error in the input file. - Provide a distinct error message for the case where p_xref fails on a cross-reference stream because of invalid data. - Only skip storing the invalid section. Try to follow the /Prev entry in the stream dictionary to find more sections. commit - 512de3c2ead8ba1a54f5b7d4e4fd9050854ccc78 commit + a1014f81d804955bb38b434865b733271aa3d7a7 blob - afd483c12119475d69038c51a3298e6e2a031211 blob + b377e34841c1a797a590f69f457d4f496789389b --- pdf.c +++ pdf.c @@ -4984,19 +4984,26 @@ parse_xrefs(const uint8_t *input, size_t sz, size_t *n for (;;) { assert(offset <= sz); res = h_parse(p_xref, input + offset, sz - offset); - if (res == NULL || res->ast == NULL || H_INDEX_TOKEN(res->ast, 0) == NULL) { + if (res == NULL) { log_message(5, "%s: error parsing xref section at " "position %zu (%#zx)\n", infile, offset, offset); break; } + assert(res->ast != NULL); - /* save this section in xrefs */ - if (n >= SIZE_MAX / sizeof(HParsedToken *)) - errx(2, "parse_xrefs: realloc: size would overflow"); - xrefs = realloc(xrefs, (n + 1) * sizeof(HParsedToken *)); - if (xrefs == NULL) - err(2, "parse_xrefs"); - xrefs[n++] = res->ast; + if (H_INDEX_TOKEN(res->ast, 0) == NULL) { + log_message(5, "%s: error parsing xref stream data at " + "position %zu (%#zx)\n", infile, offset, offset); + /* skip this section, but continue following /Prev */ + } else { + /* data is valid, save this section in xrefs */ + if (n >= SIZE_MAX / sizeof(HParsedToken *)) + errx(2, "parse_xrefs: realloc: size overflow"); + xrefs = realloc(xrefs, (n + 1) * sizeof *xrefs); + if (xrefs == NULL) + err(2, "parse_xrefs"); + xrefs[n++] = res->ast; + } /* look up the next offset (to the previous xref section) */ tok = dictentry(H_INDEX(Dict, res->ast, 1), "Prev");