summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2016-02-03 15:29:04 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2016-02-03 15:29:04 (GMT)
commit8b4717e9ad0214e985ed2fe6ee6d673b9d1cf603 (patch)
treed2a42671d16e15a6c2d8ef9a5d0530e54eb89a7f
parent2f90de6166e0253955f4e7ce895ddb63c0d4f05d (diff)
downloadtcl-8b4717e9ad0214e985ed2fe6ee6d673b9d1cf603.zip
tcl-8b4717e9ad0214e985ed2fe6ee6d673b9d1cf603.tar.gz
tcl-8b4717e9ad0214e985ed2fe6ee6d673b9d1cf603.tar.bz2
[25842c161] Prevent zero-length compress actions in [zlib] streaming API.
-rw-r--r--generic/tclZlib.c33
-rw-r--r--tests/zlib.test6
2 files changed, 24 insertions, 15 deletions
diff --git a/generic/tclZlib.c b/generic/tclZlib.c
index ba3e9cb..6f1d225 100644
--- a/generic/tclZlib.c
+++ b/generic/tclZlib.c
@@ -1164,6 +1164,14 @@ Tcl_ZlibStreamPut(
zshPtr->stream.next_in = Tcl_GetByteArrayFromObj(data, &size);
zshPtr->stream.avail_in = size;
+ /*
+ * Must not do a zero-length compress. [Bug 25842c161]
+ */
+
+ if (size == 0) {
+ return TCL_OK;
+ }
+
if (HaveDictToSet(zshPtr)) {
e = SetDeflateDictionary(&zshPtr->stream, zshPtr->compDictObj);
if (e != Z_OK) {
@@ -1186,32 +1194,27 @@ Tcl_ZlibStreamPut(
zshPtr->stream.next_out = (Bytef *) dataTmp;
e = deflate(&zshPtr->stream, flush);
- if ((e==Z_OK || e==Z_BUF_ERROR) && (zshPtr->stream.avail_out == 0)) {
- if (outSize - zshPtr->stream.avail_out > 0) {
- /*
- * Output buffer too small.
- */
-
- obj = Tcl_NewByteArrayObj((unsigned char *) dataTmp,
- outSize - zshPtr->stream.avail_out);
+ while (e == Z_BUF_ERROR) {
+ /*
+ * Output buffer too small to hold the data being generated; so
+ * put a new buffer into place after saving the old generated
+ * data to the outData list.
+ */
- /*
- * Now append the compressed data to the outData list.
- */
+ obj = Tcl_NewByteArrayObj((unsigned char *) dataTmp, outSize);
+ Tcl_ListObjAppendElement(NULL, zshPtr->outData, obj);
- Tcl_ListObjAppendElement(NULL, zshPtr->outData, obj);
- }
if (outSize < 0xFFFF) {
outSize = 0xFFFF; /* There may be *lots* of data left to
* output... */
- ckfree(dataTmp);
- dataTmp = ckalloc(outSize);
+ dataTmp = ckrealloc(dataTmp, outSize);
}
zshPtr->stream.avail_out = outSize;
zshPtr->stream.next_out = (Bytef *) dataTmp;
e = deflate(&zshPtr->stream, flush);
}
+
if (e != Z_OK && !(flush==Z_FINISH && e==Z_STREAM_END)) {
if (zshPtr->interp) {
ConvertError(zshPtr->interp, e, zshPtr->stream.adler);
diff --git a/tests/zlib.test b/tests/zlib.test
index b1d43fb..7a486ba 100644
--- a/tests/zlib.test
+++ b/tests/zlib.test
@@ -132,6 +132,12 @@ test zlib-7.6 {zlib stream} zlib {
$s close
lappend result $data
} {{} 69f34b6a abcdeEDCBA..}
+test zlib-7.7 {zlib stream: Bug 25842c161} -constraints zlib -body {
+ set s [zlib stream deflate]
+ $s put {}
+} -cleanup {
+ catch {$s close}
+} -result ""
test zlib-8.1 {zlib transformation} -constraints zlib -setup {
set file [makeFile {} test.gz]