From: Ruediger Pluem Date: Mon, 17 Jul 2006 15:08:27 +0000 (+0000) Subject: * Fix potential memory leaks in deflate_out_filter if bailing out due to an X-Git-Tag: 2.3.0~2244 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e65116b77717ea3ba30bfe71d165b77f23aab59f;p=thirdparty%2Fapache%2Fhttpd.git * Fix potential memory leaks in deflate_out_filter if bailing out due to an error (either in the lower filter chain or during a libz operation). We need to call deflateEnd as it is very likely that this filter is never called again to ensures that libz's internal structures get cleaned properly. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@422736 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/modules/filters/mod_deflate.c b/modules/filters/mod_deflate.c index 58ea9a5dbb5..3d2c80a7cb5 100644 --- a/modules/filters/mod_deflate.c +++ b/modules/filters/mod_deflate.c @@ -502,6 +502,14 @@ static apr_status_t deflate_out_filter(ap_filter_t *f, /* flush the remaining data from the zlib buffers */ zRC = flush_zlib_buffer(ctx, c, f->c->bucket_alloc, Z_SYNC_FLUSH); if (zRC != Z_OK) { + /* + * Things screwed up. It is likely that we never return into + * this filter, so clean libz's internal structures to avoid a + * possible memory leak. + */ + deflateEnd(&ctx->stream); + /* Remove ourselves to ensure that we really NEVER come back */ + ap_remove_output_filter(f); return APR_EGENERAL; } @@ -510,6 +518,14 @@ static apr_status_t deflate_out_filter(ap_filter_t *f, APR_BRIGADE_INSERT_TAIL(ctx->bb, e); rv = ap_pass_brigade(f->next, ctx->bb); if (rv != APR_SUCCESS) { + /* + * Things screwed up. It is likely that we never return into + * this filter, so clean libz's internal structures to avoid a + * possible memory leak. + */ + deflateEnd(&ctx->stream); + /* Remove ourselves to ensure that we really NEVER come back */ + ap_remove_output_filter(f); return rv; } continue; @@ -541,14 +557,31 @@ static apr_status_t deflate_out_filter(ap_filter_t *f, /* Send what we have right now to the next filter. */ rv = ap_pass_brigade(f->next, ctx->bb); if (rv != APR_SUCCESS) { + /* + * Things screwed up. It is likely that we never return into + * this filter, so clean libz's internal structures to avoid a + * possible memory leak. + */ + deflateEnd(&ctx->stream); + /* Remove ourselves to ensure that we really NEVER come back */ + ap_remove_output_filter(f); return rv; } } zRC = deflate(&(ctx->stream), Z_NO_FLUSH); - if (zRC != Z_OK) + if (zRC != Z_OK) { + /* + * Things screwed up. It is likely that we never return into + * this filter, so clean libz's internal structures to avoid a + * possible memory leak. + */ + deflateEnd(&ctx->stream); + /* Remove ourselves to ensure that we really NEVER come back */ + ap_remove_output_filter(f); return APR_EGENERAL; + } } apr_bucket_delete(e);