summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--generic/tclZlib.c25
2 files changed, 32 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 393a65a..7ba4ca5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2010-02-22 Andreas Kupries <andreask@activestate.com>
+
+ * generic/tclZlib.c (ZlibTransformInput): [Bug 2742041]: Added a
+ hack to work around the general problem, early EOF recoginition
+ based on the base-chgannel, instead of the data we have ready for
+ reading in the transform. Long-term we need a proper general fix
+ (likely tracking EOF on each level of the channel stack), with
+ attendant complexity. Further: Z_BUF_ERROR can be ignored, and
+ must be when feeding the zlib code with single characters.
+
2010-02-17 Jan Nijtmans <nijtmans@users.sf.net>
* unix/tclUnixPort.h Remove unnecessary EXTERN's, which already
diff --git a/generic/tclZlib.c b/generic/tclZlib.c
index f43f704..14212ef 100644
--- a/generic/tclZlib.c
+++ b/generic/tclZlib.c
@@ -13,7 +13,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclZlib.c,v 1.33 2010/02/08 13:21:42 dkf Exp $
+ * RCS: @(#) $Id: tclZlib.c,v 1.34 2010/02/22 23:54:24 andreas_kupries Exp $
*/
#include "tclInt.h"
@@ -2412,7 +2412,15 @@ ZlibTransformInput(
if ((e == Z_STREAM_END) || (e==Z_OK && cd->inStream.avail_out==0)) {
return toRead - cd->inStream.avail_out;
}
- if (e != Z_OK) {
+
+ /*
+ * Z_BUF_ERROR can be ignored as per http://www.zlib.net/zlib_how.html
+ *
+ * Just indicates that the zlib couldn't consume input/produce output,
+ * and is fixed by supplying more input.
+ */
+
+ if ((e != Z_OK) && (e != Z_BUF_ERROR)) {
Tcl_Obj *errObj = Tcl_NewListObj(0, NULL);
Tcl_ListObjAppendElement(NULL, errObj,
@@ -2436,7 +2444,18 @@ ZlibTransformInput(
*/
doReadFirst:
- read = Tcl_ReadRaw(cd->parent, cd->inBuffer, cd->inAllocated);
+ /*
+ * Hack for Bug 2762041. Disable pre-reading of lots of input, read
+ * only one character. This way the Z_END_OF_STREAM can be read
+ * without triggering an EOF in the base channel. The higher input
+ * loops in DoReadChars() would react to that by stopping, despite the
+ * transform still having data which could be read.
+ *
+ * This is only a hack because other transforms may not be able to
+ * work around the general problem in this way.
+ */
+
+ read = Tcl_ReadRaw(cd->parent, cd->inBuffer, 1);
if (read < 0) {
*errorCodePtr = Tcl_GetErrno();
return -1;