content_encoding: fix inflate_stream for no bytes available
authorJay Satiro <raysatiro@yahoo.com>
Tue, 7 Nov 2017 05:46:59 +0000 (00:46 -0500)
committerJay Satiro <raysatiro@yahoo.com>
Thu, 9 Nov 2017 06:36:50 +0000 (01:36 -0500)
- Don't call zlib's inflate() when avail_in stream bytes is 0.

This is a follow up to the parent commit 19e66e5. Prior to that change
libcurl's inflate_stream could call zlib's inflate even when no bytes
were available, causing inflate to return Z_BUF_ERROR, and then
inflate_stream would treat that as a hard error and return
CURLE_BAD_CONTENT_ENCODING.

According to the zlib FAQ, Z_BUF_ERROR is not fatal.

This bug would happen randomly since packet sizes are arbitrary. A test
of 10,000 transfers had 55 fail (ie 0.55%).

Ref: https://zlib.net/zlib_faq.html#faq05

Closes https://github.com/curl/curl/pull/2060

lib/content_encoding.c

index 904dff526c5cd0fa14e25162e24bb019792db8c8..626bb8ec955fd91c79cdfe981fbd123105ad2c59 100644 (file)
@@ -139,6 +139,11 @@ inflate_stream(struct connectdata *conn, contenc_writer *writer)
   /* because the buffer size is fixed, iteratively decompress and transfer to
      the client via client_write. */
   for(;;) {
+    if(z->avail_in == 0) {
+      free(decomp);
+      return result;
+    }
+
     /* (re)set buffer for decompressed output for every iteration */
     z->next_out = (Bytef *) decomp;
     z->avail_out = DSIZ;
@@ -163,10 +168,7 @@ inflate_stream(struct connectdata *conn, contenc_writer *writer)
       /* Done with these bytes, exit */
 
       /* status is always Z_OK at this point! */
-      if(z->avail_in == 0) {
-        free(decomp);
-        return result;
-      }
+      continue;
     }
     else if(allow_restart && status == Z_DATA_ERROR) {
       /* some servers seem to not generate zlib headers, so this is an attempt