diff --git a/src/comp.c b/src/comp.c
index 0296f62..ed854fe 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -248,83 +248,56 @@ comp_method_zlib_decomp(LIBSSH2_SESSION * session,
     if (!strm->next_out)
         return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
                               "Unable to allocate decompression buffer");
-    while (strm->avail_in) {
-        int status;
+
+    /* Loop until it's all inflated or hit error */
+    for (;;) {
+        int status, grow_size;
+        size_t out_ofs;
+        char *newout;
 
         status = inflate(strm, Z_PARTIAL_FLUSH);
 
-        if (status != Z_OK) {
+        if (status == Z_OK) {
+            if (! strm->avail_in) {
+                /* status is OK and input all used so we're done */
+                break;
+            }
+        } else if (status == Z_BUF_ERROR) {
+            /* This is OK, just drop through to grow the buffer */
+        } else {
+            /* error state */
             LIBSSH2_FREE(session, out);
             _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
                            "unhandled zlib error %d", status);
             return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
                                   "decompression failure");
         }
+
+        /* If we get here we need to grow the output buffer and try again */
+        out_ofs = out_maxlen - strm->avail_out;
         if (strm->avail_in) {
-            size_t out_ofs = out_maxlen - strm->avail_out;
-            char *newout;
+            grow_size = strm->avail_in * 8;
+        } else {
+            /* Not sure how much to grow by */
+            grow_size = 32;
+        }
+        out_maxlen += grow_size;
 
-            out_maxlen += 8 * strm->avail_in;
+        if ((out_maxlen > (int) payload_limit) && limiter++) {
+            LIBSSH2_FREE(session, out);
+            return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
+                                  "Excessive growth in decompression phase");
+        }
 
-            if ((out_maxlen > (int) payload_limit) && limiter++) {
-                LIBSSH2_FREE(session, out);
-                return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
-                                      "Excessive growth in decompression phase");
-            }
-
-            newout = LIBSSH2_REALLOC(session, out, out_maxlen);
-            if (!newout) {
-                LIBSSH2_FREE(session, out);
-                return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-                                      "Unable to expand decompression buffer");
-            }
-            out = newout;
-            strm->next_out = (unsigned char *) out + out_ofs;
-            strm->avail_out += 8 * strm->avail_in;
-        } else
-            while (!strm->avail_out) {
-                /* Done with input, might be a byte or two in internal buffer
-                 * during compress.  Or potentially many bytes if it's a
-                 * decompress
-                 */
-                int grow_size = 2048;
-                char *newout;
-
-                if (out_maxlen >= (int) payload_limit) {
-                    LIBSSH2_FREE(session, out);
-                    return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
-                                          "Excessive growth in decompression "
-                                          "phase");
-                }
-
-                if (grow_size > (int) (payload_limit - out_maxlen)) {
-                    grow_size = payload_limit - out_maxlen;
-                }
-
-                out_maxlen += grow_size;
-                strm->avail_out = grow_size;
-
-                newout = LIBSSH2_REALLOC(session, out, out_maxlen);
-                if (!newout) {
-                    LIBSSH2_FREE(session, out);
-                    return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-                                          "Unable to expand final "
-                                          "decompress buffer");
-                }
-                out = newout;
-                strm->next_out = (unsigned char *) out + out_maxlen -
-                    grow_size;
-
-                status = inflate(strm, Z_PARTIAL_FLUSH);
-
-                if (status != Z_OK) {
-                    LIBSSH2_FREE(session, out);
-                    _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
-                                   "unhandled zlib error %d", status);
-                    return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
-                                          "decompression failure");
-                }
-            }
+        newout = LIBSSH2_REALLOC(session, out, out_maxlen);
+        if (!newout) {
+            LIBSSH2_FREE(session, out);
+            return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
+                                  "Unable to expand decompression buffer");
+        }
+        out = newout;
+        strm->next_out = (unsigned char *) out + out_ofs;
+        strm->avail_out += grow_size;
     }
 
     *dest = (unsigned char *) out;