diff options
-rw-r--r-- | generic/tclZlib.c | 65 | ||||
-rw-r--r-- | tests/zlib.test | 8 |
2 files changed, 42 insertions, 31 deletions
diff --git a/generic/tclZlib.c b/generic/tclZlib.c index 544ba50..dc9a895 100644 --- a/generic/tclZlib.c +++ b/generic/tclZlib.c @@ -87,6 +87,15 @@ typedef struct { * opportunity. */ /* + * Macros to make it clearer in some of the twiddlier accesses what is + * happening. + */ + +#define IsRawStream(zshPtr) ((zshPtr)->format == TCL_ZLIB_FORMAT_RAW) +#define HaveDictToSet(zshPtr) ((zshPtr)->flags & DICT_TO_SET) +#define DictWasSet(zshPtr) ((zshPtr)->flags |= ~DICT_TO_SET) + +/* * Structure used for stacked channel compression and decompression. */ @@ -640,18 +649,12 @@ Tcl_ZlibStreamInit( e = deflateSetHeader(&zshPtr->stream, &zshPtr->gzHeaderPtr->header); } - if (e == Z_OK && zshPtr->compDictObj) { - e = SetDeflateDictionary(&zshPtr->stream, zshPtr->compDictObj); - } } else { e = inflateInit2(&zshPtr->stream, wbits); if (e == Z_OK && zshPtr->gzHeaderPtr) { e = inflateGetHeader(&zshPtr->stream, &zshPtr->gzHeaderPtr->header); } - if (format==TCL_ZLIB_FORMAT_RAW && zshPtr->compDictObj && e==Z_OK) { - e = SetInflateDictionary(&zshPtr->stream, zshPtr->compDictObj); - } } if (e != Z_OK) { @@ -889,14 +892,19 @@ Tcl_ZlibStreamReset( if (zshPtr->mode == TCL_ZLIB_STREAM_DEFLATE) { e = deflateInit2(&zshPtr->stream, zshPtr->level, Z_DEFLATED, zshPtr->wbits, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY); - if (e == Z_OK && zshPtr->compDictObj) { + if (e == Z_OK && HaveDictToSet(zshPtr)) { e = SetDeflateDictionary(&zshPtr->stream, zshPtr->compDictObj); + if (e == Z_OK) { + DictWasSet(zshPtr); + } } } else { e = inflateInit2(&zshPtr->stream, zshPtr->wbits); - if (zshPtr->format == TCL_ZLIB_FORMAT_RAW && zshPtr->compDictObj - && e == Z_OK) { + if (IsRawStream(zshPtr) && HaveDictToSet(zshPtr) && e == Z_OK) { e = SetInflateDictionary(&zshPtr->stream, zshPtr->compDictObj); + if (e == Z_OK) { + DictWasSet(zshPtr); + } } } @@ -1011,6 +1019,10 @@ Tcl_ZlibStreamSetCompressionDictionary( ZlibStreamHandle *zshPtr = (ZlibStreamHandle *) zshandle; if (compressionDictionaryObj != NULL) { + if (Tcl_IsShared(compressionDictionaryObj)) { + compressionDictionaryObj = + Tcl_DuplicateObj(compressionDictionaryObj); + } Tcl_IncrRefCount(compressionDictionaryObj); zshPtr->flags |= DICT_TO_SET; } else { @@ -1058,7 +1070,7 @@ Tcl_ZlibStreamPut( zshPtr->stream.next_in = Tcl_GetByteArrayFromObj(data, &size); zshPtr->stream.avail_in = size; - if (zshPtr->flags & DICT_TO_SET) { + if (HaveDictToSet(zshPtr)) { e = SetDeflateDictionary(&zshPtr->stream, zshPtr->compDictObj); if (e != Z_OK) { if (zshPtr->interp) { @@ -1066,7 +1078,7 @@ Tcl_ZlibStreamPut( } return TCL_ERROR; } - zshPtr->flags &= ~DICT_TO_SET; + DictWasSet(zshPtr); } /* @@ -1243,20 +1255,21 @@ Tcl_ZlibStreamGet( * don't ever issue that.) */ - if (zshPtr->format == TCL_ZLIB_FORMAT_RAW && zshPtr->compDictObj) { + if (IsRawStream(zshPtr) && HaveDictToSet(zshPtr)) { e = SetInflateDictionary(&zshPtr->stream, zshPtr->compDictObj); if (e != Z_OK) { - ConvertError(zshPtr->interp, e, zshPtr->stream.adler); + if (zshPtr->interp) { + ConvertError(zshPtr->interp, e, zshPtr->stream.adler); + } return TCL_ERROR; } - Tcl_DecrRefCount(zshPtr->compDictObj); - zshPtr->compDictObj = NULL; + DictWasSet(zshPtr); } - e = inflate(&zshPtr->stream, zshPtr->flush); - if (e == Z_NEED_DICT && zshPtr->compDictObj) { + if (e == Z_NEED_DICT && HaveDictToSet(zshPtr)) { e = SetInflateDictionary(&zshPtr->stream, zshPtr->compDictObj); if (e == Z_OK) { + DictWasSet(zshPtr); e = inflate(&zshPtr->stream, zshPtr->flush); } }; @@ -1313,13 +1326,14 @@ Tcl_ZlibStreamGet( * And call inflate again. */ - e = inflate(&zshPtr->stream, zshPtr->flush); - if (e == Z_NEED_DICT && zshPtr->compDictObj) { - e = SetInflateDictionary(&zshPtr->stream,zshPtr->compDictObj); - if (e == Z_OK) { - e = inflate(&zshPtr->stream, zshPtr->flush); + do { + e = inflate(&zshPtr->stream, zshPtr->flush); + if (e != Z_NEED_DICT || !HaveDictToSet(zshPtr)) { + break; } - } + e = SetInflateDictionary(&zshPtr->stream,zshPtr->compDictObj); + DictWasSet(zshPtr); + } while (e == Z_OK); } if (zshPtr->stream.avail_out > 0) { Tcl_SetByteArrayLength(data, @@ -2158,10 +2172,7 @@ ZlibStreamSubcmd( return TCL_ERROR; } if (compDictObj != NULL) { - ZlibStreamHandle *zshPtr = (ZlibStreamHandle *) zh; - - zshPtr->compDictObj = compDictObj; - Tcl_IncrRefCount(compDictObj); + Tcl_ZlibStreamSetCompressionDictionary(zh, compDictObj); } Tcl_SetObjResult(interp, Tcl_ZlibStreamGetCommandName(zh)); return TCL_OK; diff --git a/tests/zlib.test b/tests/zlib.test index 5d46926..9058817 100644 --- a/tests/zlib.test +++ b/tests/zlib.test @@ -293,15 +293,15 @@ test zlib-8.11 {transformtion and fconfigure} -setup { catch {close $inSide} catch {$strm close} } -result {358 358} -test zlib-8.13 {transformtion and fconfigure} -setup { +test zlib-8.12 {transformtion and fconfigure} -setup { lassign [chan pipe] inSide outSide set strm [zlib stream compress] -} -constraints {zlib knownBug} -body { - set data [$strm add -dictionary $spdyDict $spdyHeaders] +} -constraints zlib -body { + $strm put -dictionary $spdyDict -finalize $spdyHeaders zlib push decompress $inSide fconfigure $outSide -blocking 0 -translation binary fconfigure $inSide -translation binary -dictionary $spdyDict - puts -nonewline $outSide $data + puts -nonewline $outSide [$strm get] close $outSide list [string length $spdyHeaders] [string length [read $inSide]] } -cleanup { |