diff options
author | Sebastian Rasmussen <sebras@gmail.com> | 2016-09-27 16:46:25 +0800 |
---|---|---|
committer | Sebastian Rasmussen <sebras@gmail.com> | 2016-09-28 00:11:22 +0800 |
commit | c8b6591643d341f729de073c468ce1f27e178a9e (patch) | |
tree | 36ba501a15591599a11fdd7c3d58815e6735e8e3 /source | |
parent | c60de04ff82b6232f702b40fea1c7fd0876ba29f (diff) | |
download | mupdf-c8b6591643d341f729de073c468ce1f27e178a9e.tar.xz |
tiff: Validate that tag/tile/strip offsets are within bounds.
Diffstat (limited to 'source')
-rw-r--r-- | source/fitz/load-tiff.c | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/source/fitz/load-tiff.c b/source/fitz/load-tiff.c index ca3b71cc..7bf0d163 100644 --- a/source/fitz/load-tiff.c +++ b/source/fitz/load-tiff.c @@ -533,6 +533,11 @@ fz_decode_tiff_tiles(fz_context *ctx, struct tiff *tiff) unsigned int rlen = tiff->tilebytecounts[tile]; unsigned char *rp = tiff->bp + offset; + if (offset > (unsigned)(tiff->ep - tiff->bp)) + fz_throw(ctx, FZ_ERROR_GENERIC, "invalid tile offset %u", offset); + if (rlen > (unsigned)(tiff->ep - rp)) + fz_throw(ctx, FZ_ERROR_GENERIC, "invalid tile byte count %u", rlen); + if (fz_decode_tiff_chunk(ctx, tiff, rp, rlen, wp, wlen) != wlen) fz_throw(ctx, FZ_ERROR_GENERIC, "decoded tile is the wrong size"); @@ -564,6 +569,11 @@ fz_decode_tiff_strips(fz_context *ctx, struct tiff *tiff) unsigned wlen = tiff->stride * tiff->rowsperstrip; unsigned char *rp = tiff->bp + offset; + if (offset > (unsigned)(tiff->ep - tiff->bp)) + fz_throw(ctx, FZ_ERROR_GENERIC, "invalid strip offset %u", offset); + if (rlen > (unsigned)(tiff->ep - rp)) + fz_throw(ctx, FZ_ERROR_GENERIC, "invalid strip byte count %u", rlen); + if (y + tiff->rowsperstrip >= tiff->imagelength) wlen = tiff->stride * (tiff->imagelength - y); @@ -576,7 +586,6 @@ fz_decode_tiff_strips(fz_context *ctx, struct tiff *tiff) wp += wlen; strip ++; } - } static inline int readbyte(struct tiff *tiff) @@ -609,9 +618,9 @@ static inline unsigned readlong(struct tiff *tiff) static void fz_read_tiff_bytes(unsigned char *p, struct tiff *tiff, unsigned ofs, unsigned n) { + if (ofs > (unsigned)(tiff->ep - tiff->bp)) + ofs = (unsigned)(tiff->ep - tiff->bp); tiff->rp = tiff->bp + ofs; - if (tiff->rp > tiff->ep) - tiff->rp = tiff->bp; while (n--) *p++ = readbyte(tiff); @@ -622,9 +631,9 @@ fz_read_tiff_tag_value(unsigned *p, struct tiff *tiff, unsigned type, unsigned o { unsigned den; + if (ofs > (unsigned)(tiff->ep - tiff->bp)) + ofs = (unsigned)(tiff->ep - tiff->bp); tiff->rp = tiff->bp + ofs; - if (tiff->rp > tiff->ep) - tiff->rp = tiff->bp; while (n--) { @@ -852,11 +861,10 @@ fz_next_ifd(fz_context *ctx, struct tiff *tiff, unsigned offset) { unsigned count; - tiff->rp = tiff->bp + offset; - - if (tiff->rp <= tiff->bp || tiff->rp > tiff->ep) + if (offset > (unsigned)(tiff->ep - tiff->bp)) fz_throw(ctx, FZ_ERROR_GENERIC, "invalid IFD offset %u", offset); + tiff->rp = tiff->bp + offset; count = readshort(tiff); if (count * 12 > (unsigned)(tiff->ep - tiff->rp)) |