]> granicus.if.org Git - apache/commitdiff
Fix memory leak in mod_deflate.c when SetOutputFilter is enabled and DEFLATE
authorJustin Erenkrantz <jerenkrantz@apache.org>
Sun, 15 May 2011 11:05:36 +0000 (11:05 +0000)
committerJustin Erenkrantz <jerenkrantz@apache.org>
Sun, 15 May 2011 11:05:36 +0000 (11:05 +0000)
is the first filter in the chain - this is seen with mod_dav + mod_deflate
when the client can not do gzip and we constantly do the filter checks.

* modules/filters/mod_deflate.c
  (deflate_ctx): Add a flag as to whether we are successfully initialized.
  (deflate_out_filter): Always create filter ctx and set filter_init flag only
  after we are successfully initialized.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1103315 13f79535-47bb-0310-9956-ffa450edef68

modules/filters/mod_deflate.c

index 9f41b815894e3e0088288384c10e640ba3ad199b..a11c6022be1e150cba61d843240515a87467f223 100644 (file)
@@ -303,6 +303,7 @@ typedef struct deflate_ctx_t
     unsigned char *validation_buffer;
     apr_size_t validation_buffer_length;
     int inflate_init;
+    int filter_init;
 } deflate_ctx;
 
 /* Number of validation bytes (CRC and length) after the compressed data */
@@ -445,6 +446,8 @@ static apr_status_t deflate_out_filter(ap_filter_t *f,
         char *token;
         const char *encoding;
 
+        ctx = f->ctx = apr_pcalloc(r->pool, sizeof(*ctx));
+
         /*
          * Only work on main request, not subrequests,
          * that are not a 204 response with no content
@@ -563,7 +566,6 @@ static apr_status_t deflate_out_filter(ap_filter_t *f,
          */
 
         if (r->status != HTTP_NOT_MODIFIED) {
-            ctx = f->ctx = apr_pcalloc(r->pool, sizeof(*ctx));
             ctx->bb = apr_brigade_create(r->pool, f->c->bucket_alloc);
             ctx->buffer = apr_palloc(r->pool, c->bufferSize);
             ctx->libz_end_func = deflateEnd;
@@ -592,6 +594,11 @@ static apr_status_t deflate_out_filter(ap_filter_t *f,
              */
             apr_pool_cleanup_register(r->pool, ctx, deflate_ctx_cleanup,
                                       apr_pool_cleanup_null);
+
+            /* Set the filter init flag so subsequent invocations know we are
+             * active.
+             */
+            ctx->filter_init = 1;
         }
 
         /*
@@ -629,6 +636,11 @@ static apr_status_t deflate_out_filter(ap_filter_t *f,
         /* initialize deflate output buffer */
         ctx->stream.next_out = ctx->buffer;
         ctx->stream.avail_out = c->bufferSize;
+    } else if (!ctx->filter_init) {
+        /* Hmm.  We've run through the filter init before as we have a ctx,
+         * but we never initialized.  We probably have a dangling ref.  Bail.
+         */
+        return ap_pass_brigade(f->next, bb);
     }
 
     while (!APR_BRIGADE_EMPTY(bb))