summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2019-02-19 15:10:36 +0100
committerEven Rouault <even.rouault@spatialys.com>2019-02-19 15:10:36 +0100
commit2ff9c01bd926a21a5f9c0e4c756b353dc692d2c2 (patch)
treea4becdc2d2459cf008b22f9eb2feb1ff8c9d37f4
parent0489f1f87991a0f73060780bc3642f21077430a3 (diff)
downloadlibtiff-git-2ff9c01bd926a21a5f9c0e4c756b353dc692d2c2.tar.gz
tif_zip.c: allow reading and writing strips/tiles with more than 4 GB of compressed or uncompressed data
-rw-r--r--libtiff/tif_zip.c54
1 files changed, 19 insertions, 35 deletions
diff --git a/libtiff/tif_zip.c b/libtiff/tif_zip.c
index b71c44e8..9e2b5ebd 100644
--- a/libtiff/tif_zip.c
+++ b/libtiff/tif_zip.c
@@ -124,7 +124,6 @@ ZIPSetupDecode(TIFF* tif)
static int
ZIPPreDecode(TIFF* tif, uint16 s)
{
- static const char module[] = "ZIPPreDecode";
ZIPState* sp = DecoderState(tif);
(void) s;
@@ -138,12 +137,7 @@ ZIPPreDecode(TIFF* tif, uint16 s)
we need to simplify this code to reflect a ZLib that is likely updated
to deal with 8byte memory sizes, though this code will respond
appropriately even before we simplify it */
- sp->stream.avail_in = (uInt) tif->tif_rawcc;
- if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc)
- {
- TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
- return (0);
- }
+ sp->stream.avail_in = (uint64)tif->tif_rawcc < 0xFFFFFFFFU ? (uInt) tif->tif_rawcc : 0xFFFFFFFFU;
return (inflateReset(&sp->stream) == Z_OK);
}
@@ -158,21 +152,21 @@ ZIPDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
assert(sp->state == ZSTATE_INIT_DECODE);
sp->stream.next_in = tif->tif_rawcp;
- sp->stream.avail_in = (uInt) tif->tif_rawcc;
sp->stream.next_out = op;
assert(sizeof(sp->stream.avail_out)==4); /* if this assert gets raised,
we need to simplify this code to reflect a ZLib that is likely updated
to deal with 8byte memory sizes, though this code will respond
appropriately even before we simplify it */
- sp->stream.avail_out = (uInt) occ;
- if ((tmsize_t)sp->stream.avail_out != occ)
- {
- TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
- return (0);
- }
do {
- int state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
+ int state;
+ uInt avail_in_before = (uint64)tif->tif_rawcc <= 0xFFFFFFFFU ? (uInt)tif->tif_rawcc : 0xFFFFFFFFU;
+ uInt avail_out_before = (uint64)occ < 0xFFFFFFFFU ? (uInt) occ : 0xFFFFFFFFU;
+ sp->stream.avail_in = avail_in_before;
+ sp->stream.avail_out = avail_out_before;
+ state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
+ tif->tif_rawcc -= (avail_in_before - sp->stream.avail_in);
+ occ -= (avail_out_before - sp->stream.avail_out);
if (state == Z_STREAM_END)
break;
if (state == Z_DATA_ERROR) {
@@ -188,16 +182,15 @@ ZIPDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
"ZLib error: %s", SAFE_MSG(sp));
return (0);
}
- } while (sp->stream.avail_out > 0);
- if (sp->stream.avail_out != 0) {
+ } while (occ > 0);
+ if (occ != 0) {
TIFFErrorExt(tif->tif_clientdata, module,
"Not enough data at scanline %lu (short " TIFF_UINT64_FORMAT " bytes)",
- (unsigned long) tif->tif_row, (TIFF_UINT64_T) sp->stream.avail_out);
+ (unsigned long) tif->tif_row, (TIFF_UINT64_T) occ);
return (0);
}
tif->tif_rawcp = sp->stream.next_in;
- tif->tif_rawcc = sp->stream.avail_in;
return (1);
}
@@ -229,7 +222,6 @@ ZIPSetupEncode(TIFF* tif)
static int
ZIPPreEncode(TIFF* tif, uint16 s)
{
- static const char module[] = "ZIPPreEncode";
ZIPState *sp = EncoderState(tif);
(void) s;
@@ -242,12 +234,7 @@ ZIPPreEncode(TIFF* tif, uint16 s)
we need to simplify this code to reflect a ZLib that is likely updated
to deal with 8byte memory sizes, though this code will respond
appropriately even before we simplify it */
- sp->stream.avail_out = (uInt)tif->tif_rawdatasize;
- if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
- {
- TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
- return (0);
- }
+ sp->stream.avail_out = (uint64)tif->tif_rawdatasize <= 0xFFFFFFFFU ? (uInt)tif->tif_rawdatasize : 0xFFFFFFFFU;
return (deflateReset(&sp->stream) == Z_OK);
}
@@ -269,13 +256,9 @@ ZIPEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
we need to simplify this code to reflect a ZLib that is likely updated
to deal with 8byte memory sizes, though this code will respond
appropriately even before we simplify it */
- sp->stream.avail_in = (uInt) cc;
- if ((tmsize_t)sp->stream.avail_in != cc)
- {
- TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
- return (0);
- }
do {
+ uInt avail_in_before = (uint64)cc <= 0xFFFFFFFFU ? (uInt)cc : 0xFFFFFFFFU;
+ sp->stream.avail_in = avail_in_before;
if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) {
TIFFErrorExt(tif->tif_clientdata, module,
"Encoder error: %s",
@@ -286,9 +269,10 @@ ZIPEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
tif->tif_rawcc = tif->tif_rawdatasize;
TIFFFlushData1(tif);
sp->stream.next_out = tif->tif_rawdata;
- sp->stream.avail_out = (uInt) tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in ZIPPreEncode */
+ sp->stream.avail_out = (uint64)tif->tif_rawdatasize <= 0xFFFFFFFFU ? (uInt)tif->tif_rawdatasize : 0xFFFFFFFFU;
}
- } while (sp->stream.avail_in > 0);
+ cc -= (avail_in_before - sp->stream.avail_in);
+ } while (cc > 0);
return (1);
}
@@ -314,7 +298,7 @@ ZIPPostEncode(TIFF* tif)
tif->tif_rawcc = tif->tif_rawdatasize - sp->stream.avail_out;
TIFFFlushData1(tif);
sp->stream.next_out = tif->tif_rawdata;
- sp->stream.avail_out = (uInt) tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in ZIPPreEncode */
+ sp->stream.avail_out = (uint64)tif->tif_rawdatasize <= 0xFFFFFFFFU ? (uInt)tif->tif_rawdatasize : 0xFFFFFFFFU;
}
break;
default: