diff options
author | dkf <donal.k.fellows@manchester.ac.uk> | 2016-02-03 15:29:04 (GMT) |
---|---|---|
committer | dkf <donal.k.fellows@manchester.ac.uk> | 2016-02-03 15:29:04 (GMT) |
commit | 8b4717e9ad0214e985ed2fe6ee6d673b9d1cf603 (patch) | |
tree | d2a42671d16e15a6c2d8ef9a5d0530e54eb89a7f | |
parent | 2f90de6166e0253955f4e7ce895ddb63c0d4f05d (diff) | |
download | tcl-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.c | 33 | ||||
-rw-r--r-- | tests/zlib.test | 6 |
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] |