summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorSebastian Rasmussen <sebras@gmail.com>2018-04-17 02:32:23 +0800
committerTor Andersson <tor.andersson@artifex.com>2018-04-20 10:41:43 +0200
commitdb4e21fea6c156f8b2b710937cbee1e7e8d7b7c2 (patch)
treeecd16f7ba4cae58406c0ae380c47f49d4e81213e /source
parent53a79b1be33adfe7109da837906a4ca22818bfe3 (diff)
downloadmupdf-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')
-rw-r--r--source/pdf/pdf-xref.c36
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)