diff options
author | Sebastian Rasmussen <sebras@gmail.com> | 2018-04-17 02:32:23 +0800 |
---|---|---|
committer | Tor Andersson <tor.andersson@artifex.com> | 2018-04-20 10:41:43 +0200 |
commit | db4e21fea6c156f8b2b710937cbee1e7e8d7b7c2 (patch) | |
tree | ecd16f7ba4cae58406c0ae380c47f49d4e81213e /source/pdf | |
parent | 53a79b1be33adfe7109da837906a4ca22818bfe3 (diff) | |
download | mupdf-db4e21fea6c156f8b2b710937cbee1e7e8d7b7c2.tar.xz |
Limit xref parser to read entry contents.
Previously if an xref entry looked like:
0000000000 65535 f
1 0 n
2
the xref entry parsing would try to access the scratch buffer
outside of the part populated by the read leading to possibly
using uninitalized data.
Diffstat (limited to 'source/pdf')
-rw-r--r-- | source/pdf/pdf-xref.c | 36 |
1 files changed, 26 insertions, 10 deletions
diff --git a/source/pdf/pdf-xref.c b/source/pdf/pdf-xref.c index 2d26cdd1..158ffbf5 100644 --- a/source/pdf/pdf-xref.c +++ b/source/pdf/pdf-xref.c @@ -833,7 +833,7 @@ pdf_read_old_xref(fz_context *ctx, pdf_document *doc, pdf_lexbuf *buf) pdf_xref_entry *table; pdf_token tok; size_t n; - char *s; + char *s, *e; xref_len = pdf_xref_size_from_old_trailer(ctx, doc, buf); @@ -885,24 +885,40 @@ pdf_read_old_xref(fz_context *ctx, pdf_document *doc, pdf_lexbuf *buf) if (n != 20-carried) fz_throw(ctx, FZ_ERROR_GENERIC, "unexpected EOF in xref table"); n += carried; + buf->scratch[n] = '\0'; if (!entry->type) { s = buf->scratch; + e = s + n; + + entry->num = start + i; /* broken pdfs where line start with white space */ - while (*s != '\0' && iswhite(*s)) + while (s < e && iswhite(*s)) s++; - entry->ofs = fz_atoi64(s); - entry->gen = fz_atoi(s + 11); - entry->num = start + i; - entry->type = s[17]; - if (s[17] != 'f' && s[17] != 'n' && s[17] != 'o') - fz_throw(ctx, FZ_ERROR_GENERIC, "unexpected xref type: 0x%x (%d %d R)", s[17], entry->num, entry->gen); + if (s == e || !isdigit(*s)) + fz_throw(ctx, FZ_ERROR_GENERIC, "xref offset missing"); + while (s < e && isdigit(*s)) + entry->ofs = entry->ofs * 10 + *s++ - '0'; + + while (s < e && iswhite(*s)) + s++; + if (s == e || !isdigit(*s)) + fz_throw(ctx, FZ_ERROR_GENERIC, "xref generation number missing"); + while (s < e && isdigit(*s)) + entry->gen = entry->gen * 10 + *s++ - '0'; + + while (s < e && iswhite(*s)) + s++; + if (s == e || (*s != 'f' && *s != 'n' && *s != 'o')) + fz_throw(ctx, FZ_ERROR_GENERIC, "unexpected xref type: 0x%x (%d %d R)", s == e ? 0 : *s, entry->num, entry->gen); + entry->type = *s++; + /* If the last byte of our buffer isn't an EOL (or space), carry one byte forward */ - carried = s[19] > 32; + carried = buf->scratch[19] > 32; if (carried) - s[0] = s[19]; + buf->scratch[0] = buf->scratch[19]; } } if (carried) |