summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorSebastian Rasmussen <sebras@gmail.com>2016-09-27 16:46:25 +0800
committerSebastian Rasmussen <sebras@gmail.com>2016-09-28 00:11:22 +0800
commitc8b6591643d341f729de073c468ce1f27e178a9e (patch)
tree36ba501a15591599a11fdd7c3d58815e6735e8e3 /source
parentc60de04ff82b6232f702b40fea1c7fd0876ba29f (diff)
downloadmupdf-c8b6591643d341f729de073c468ce1f27e178a9e.tar.xz
tiff: Validate that tag/tile/strip offsets are within bounds.
Diffstat (limited to 'source')
-rw-r--r--source/fitz/load-tiff.c24
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))