Skip to content

Commit cecb25e

Browse files
ylavicnotroj
authored andcommitted
mod_deflate:
- fix signed/unsigned (int/size_t) comparisons, - add consume_buffer() to factorize code used multiple times, - cleanup passed brigade (don't rely on next output filters to do it). git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1619486 13f79535-47bb-0310-9956-ffa450edef68 (cherry picked from commit 2b94587)
1 parent 9f86c0a commit cecb25e

File tree

1 file changed

+55
-90
lines changed

1 file changed

+55
-90
lines changed

modules/filters/mod_deflate.c

+55-90
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ typedef struct deflate_filter_config_t
6666
int windowSize;
6767
int memlevel;
6868
int compressionlevel;
69-
apr_size_t bufferSize;
69+
int bufferSize;
7070
const char *note_ratio_name;
7171
const char *note_input_name;
7272
const char *note_output_name;
@@ -254,7 +254,7 @@ static const char *deflate_set_buffer_size(cmd_parms *cmd, void *dummy,
254254
return "DeflateBufferSize should be positive";
255255
}
256256

257-
c->bufferSize = (apr_size_t)n;
257+
c->bufferSize = n;
258258

259259
return NULL;
260260
}
@@ -416,35 +416,40 @@ typedef struct deflate_ctx_t
416416
/* Do update ctx->crc, see comment in flush_libz_buffer */
417417
#define UPDATE_CRC 1
418418

419+
static void consume_buffer(deflate_ctx *ctx, deflate_filter_config *c,
420+
int len, int crc, apr_bucket_brigade *bb)
421+
{
422+
apr_bucket *b;
423+
424+
/*
425+
* Do we need to update ctx->crc? Usually this is the case for
426+
* inflate action where we need to do a crc on the output, whereas
427+
* in the deflate case we need to do a crc on the input
428+
*/
429+
if (crc) {
430+
ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len);
431+
}
432+
433+
b = apr_bucket_heap_create((char *)ctx->buffer, len, NULL,
434+
bb->bucket_alloc);
435+
APR_BRIGADE_INSERT_TAIL(bb, b);
436+
437+
ctx->stream.next_out = ctx->buffer;
438+
ctx->stream.avail_out = c->bufferSize;
439+
}
440+
419441
static int flush_libz_buffer(deflate_ctx *ctx, deflate_filter_config *c,
420-
struct apr_bucket_alloc_t *bucket_alloc,
421442
int (*libz_func)(z_streamp, int), int flush,
422443
int crc)
423444
{
424445
int zRC = Z_OK;
425446
int done = 0;
426-
unsigned int deflate_len;
427-
apr_bucket *b;
447+
int deflate_len;
428448

429449
for (;;) {
430450
deflate_len = c->bufferSize - ctx->stream.avail_out;
431-
432-
if (deflate_len != 0) {
433-
/*
434-
* Do we need to update ctx->crc? Usually this is the case for
435-
* inflate action where we need to do a crc on the output, whereas
436-
* in the deflate case we need to do a crc on the input
437-
*/
438-
if (crc) {
439-
ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer,
440-
deflate_len);
441-
}
442-
b = apr_bucket_heap_create((char *)ctx->buffer,
443-
deflate_len, NULL,
444-
bucket_alloc);
445-
APR_BRIGADE_INSERT_TAIL(ctx->bb, b);
446-
ctx->stream.next_out = ctx->buffer;
447-
ctx->stream.avail_out = c->bufferSize;
451+
if (deflate_len > 0) {
452+
consume_buffer(ctx, c, deflate_len, crc, ctx->bb);
448453
}
449454

450455
if (done)
@@ -560,6 +565,7 @@ static apr_status_t deflate_out_filter(ap_filter_t *f,
560565
request_rec *r = f->r;
561566
deflate_ctx *ctx = f->ctx;
562567
int zRC;
568+
apr_status_t rv;
563569
apr_size_t len = 0, blen;
564570
const char *data;
565571
deflate_filter_config *c;
@@ -891,8 +897,7 @@ static apr_status_t deflate_out_filter(ap_filter_t *f,
891897

892898
ctx->stream.avail_in = 0; /* should be zero already anyway */
893899
/* flush the remaining data from the zlib buffers */
894-
flush_libz_buffer(ctx, c, f->c->bucket_alloc, deflate, Z_FINISH,
895-
NO_UPDATE_CRC);
900+
flush_libz_buffer(ctx, c, deflate, Z_FINISH, NO_UPDATE_CRC);
896901

897902
buf = apr_palloc(r->pool, VALIDATION_SIZE);
898903
putLong((unsigned char *)&buf[0], ctx->crc);
@@ -945,15 +950,15 @@ static apr_status_t deflate_out_filter(ap_filter_t *f,
945950
/* Okay, we've seen the EOS.
946951
* Time to pass it along down the chain.
947952
*/
948-
return ap_pass_brigade(f->next, ctx->bb);
953+
rv = ap_pass_brigade(f->next, ctx->bb);
954+
apr_brigade_cleanup(ctx->bb);
955+
return rv;
949956
}
950957

951958
if (APR_BUCKET_IS_FLUSH(e)) {
952-
apr_status_t rv;
953-
954959
/* flush the remaining data from the zlib buffers */
955-
zRC = flush_libz_buffer(ctx, c, f->c->bucket_alloc, deflate,
956-
Z_SYNC_FLUSH, NO_UPDATE_CRC);
960+
zRC = flush_libz_buffer(ctx, c, deflate, Z_SYNC_FLUSH,
961+
NO_UPDATE_CRC);
957962
if (zRC != Z_OK) {
958963
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01385)
959964
"Zlib error %d flushing zlib output buffer (%s)",
@@ -965,6 +970,7 @@ static apr_status_t deflate_out_filter(ap_filter_t *f,
965970
APR_BUCKET_REMOVE(e);
966971
APR_BRIGADE_INSERT_TAIL(ctx->bb, e);
967972
rv = ap_pass_brigade(f->next, ctx->bb);
973+
apr_brigade_cleanup(ctx->bb);
968974
if (rv != APR_SUCCESS) {
969975
return rv;
970976
}
@@ -999,21 +1005,15 @@ static apr_status_t deflate_out_filter(ap_filter_t *f,
9991005
ctx->stream.next_in = (unsigned char *)data; /* We just lost const-ness,
10001006
* but we'll just have to
10011007
* trust zlib */
1002-
ctx->stream.avail_in = len;
1008+
ctx->stream.avail_in = (int)len;
10031009

10041010
while (ctx->stream.avail_in != 0) {
10051011
if (ctx->stream.avail_out == 0) {
1006-
apr_status_t rv;
1007-
1008-
ctx->stream.next_out = ctx->buffer;
1009-
len = c->bufferSize - ctx->stream.avail_out;
1012+
consume_buffer(ctx, c, c->bufferSize, NO_UPDATE_CRC, ctx->bb);
10101013

1011-
b = apr_bucket_heap_create((char *)ctx->buffer, len,
1012-
NULL, f->c->bucket_alloc);
1013-
APR_BRIGADE_INSERT_TAIL(ctx->bb, b);
1014-
ctx->stream.avail_out = c->bufferSize;
10151014
/* Send what we have right now to the next filter. */
10161015
rv = ap_pass_brigade(f->next, ctx->bb);
1016+
apr_brigade_cleanup(ctx->bb);
10171017
if (rv != APR_SUCCESS) {
10181018
return rv;
10191019
}
@@ -1340,14 +1340,8 @@ static apr_status_t deflate_in_filter(ap_filter_t *f,
13401340
return APR_EINVAL;
13411341
}
13421342

1343-
len = c->bufferSize - ctx->stream.avail_out;
1344-
ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len);
1345-
tmp_b = apr_bucket_heap_create((char *)ctx->buffer, len,
1346-
NULL, f->c->bucket_alloc);
1347-
APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, tmp_b);
1348-
1349-
ctx->stream.next_out = ctx->buffer;
1350-
ctx->stream.avail_out = c->bufferSize;
1343+
consume_buffer(ctx, c, c->bufferSize - ctx->stream.avail_out,
1344+
UPDATE_CRC, ctx->proc_bb);
13511345

13521346
/* Flush everything so far in the returning brigade, but continue
13531347
* reading should EOS/more follow (don't lose them).
@@ -1393,16 +1387,8 @@ static apr_status_t deflate_in_filter(ap_filter_t *f,
13931387
if (!ctx->validation_buffer) {
13941388
while (ctx->stream.avail_in != 0) {
13951389
if (ctx->stream.avail_out == 0) {
1396-
apr_bucket *tmp_heap;
1397-
1398-
ctx->stream.next_out = ctx->buffer;
1399-
len = c->bufferSize - ctx->stream.avail_out;
1400-
1401-
ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len);
1402-
tmp_heap = apr_bucket_heap_create((char *)ctx->buffer, len,
1403-
NULL, f->c->bucket_alloc);
1404-
APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, tmp_heap);
1405-
ctx->stream.avail_out = c->bufferSize;
1390+
consume_buffer(ctx, c, c->bufferSize, UPDATE_CRC,
1391+
ctx->proc_bb);
14061392
}
14071393

14081394
ctx->inflate_total += ctx->stream.avail_out;
@@ -1445,7 +1431,6 @@ static apr_status_t deflate_in_filter(ap_filter_t *f,
14451431
}
14461432

14471433
if (ctx->validation_buffer) {
1448-
apr_bucket *tmp_heap;
14491434
apr_size_t avail, valid;
14501435
unsigned char *buf = ctx->validation_buffer;
14511436

@@ -1474,13 +1459,8 @@ static apr_status_t deflate_in_filter(ap_filter_t *f,
14741459
(apr_uint64_t)ctx->stream.total_in,
14751460
(apr_uint64_t)ctx->stream.total_out, r->uri);
14761461

1477-
len = c->bufferSize - ctx->stream.avail_out;
1478-
1479-
ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len);
1480-
tmp_heap = apr_bucket_heap_create((char *)ctx->buffer, len,
1481-
NULL, f->c->bucket_alloc);
1482-
APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, tmp_heap);
1483-
ctx->stream.avail_out = c->bufferSize;
1462+
consume_buffer(ctx, c, c->bufferSize - ctx->stream.avail_out,
1463+
UPDATE_CRC, ctx->proc_bb);
14841464

14851465
{
14861466
unsigned long compCRC, compLen;
@@ -1526,16 +1506,8 @@ static apr_status_t deflate_in_filter(ap_filter_t *f,
15261506
if (block == APR_BLOCK_READ &&
15271507
APR_BRIGADE_EMPTY(ctx->proc_bb) &&
15281508
ctx->stream.avail_out < c->bufferSize) {
1529-
apr_bucket *tmp_heap;
1530-
apr_size_t len;
1531-
ctx->stream.next_out = ctx->buffer;
1532-
len = c->bufferSize - ctx->stream.avail_out;
1533-
1534-
ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len);
1535-
tmp_heap = apr_bucket_heap_create((char *)ctx->buffer, len,
1536-
NULL, f->c->bucket_alloc);
1537-
APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, tmp_heap);
1538-
ctx->stream.avail_out = c->bufferSize;
1509+
consume_buffer(ctx, c, c->bufferSize - ctx->stream.avail_out,
1510+
UPDATE_CRC, ctx->proc_bb);
15391511
}
15401512

15411513
if (!APR_BRIGADE_EMPTY(ctx->proc_bb)) {
@@ -1651,7 +1623,6 @@ static apr_status_t inflate_out_filter(ap_filter_t *f,
16511623
while (!APR_BRIGADE_EMPTY(bb))
16521624
{
16531625
const char *data;
1654-
apr_bucket *b;
16551626
apr_size_t len;
16561627

16571628
e = APR_BRIGADE_FIRST(bb);
@@ -1673,8 +1644,7 @@ static apr_status_t inflate_out_filter(ap_filter_t *f,
16731644
* fails, whereas in the deflate case you can empty a filled output
16741645
* buffer and call it again until no more output can be created.
16751646
*/
1676-
flush_libz_buffer(ctx, c, f->c->bucket_alloc, inflate, Z_SYNC_FLUSH,
1677-
UPDATE_CRC);
1647+
flush_libz_buffer(ctx, c, inflate, Z_SYNC_FLUSH, UPDATE_CRC);
16781648
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01398)
16791649
"Zlib: Inflated %" APR_UINT64_T_FMT
16801650
" to %" APR_UINT64_T_FMT " : URL %s",
@@ -1716,15 +1686,14 @@ static apr_status_t inflate_out_filter(ap_filter_t *f,
17161686
* Okay, we've seen the EOS.
17171687
* Time to pass it along down the chain.
17181688
*/
1719-
return ap_pass_brigade(f->next, ctx->bb);
1689+
rv = ap_pass_brigade(f->next, ctx->bb);
1690+
apr_brigade_cleanup(ctx->bb);
1691+
return rv;
17201692
}
17211693

17221694
if (APR_BUCKET_IS_FLUSH(e)) {
1723-
apr_status_t rv;
1724-
17251695
/* flush the remaining data from the zlib buffers */
1726-
zRC = flush_libz_buffer(ctx, c, f->c->bucket_alloc, inflate,
1727-
Z_SYNC_FLUSH, UPDATE_CRC);
1696+
zRC = flush_libz_buffer(ctx, c, inflate, Z_SYNC_FLUSH, UPDATE_CRC);
17281697
if (zRC == Z_STREAM_END) {
17291698
if (ctx->validation_buffer == NULL) {
17301699
ctx->validation_buffer = apr_pcalloc(f->r->pool,
@@ -1742,6 +1711,7 @@ static apr_status_t inflate_out_filter(ap_filter_t *f,
17421711
APR_BUCKET_REMOVE(e);
17431712
APR_BRIGADE_INSERT_TAIL(ctx->bb, e);
17441713
rv = ap_pass_brigade(f->next, ctx->bb);
1714+
apr_brigade_cleanup(ctx->bb);
17451715
if (rv != APR_SUCCESS) {
17461716
return rv;
17471717
}
@@ -1858,16 +1828,11 @@ static apr_status_t inflate_out_filter(ap_filter_t *f,
18581828

18591829
while (ctx->stream.avail_in != 0) {
18601830
if (ctx->stream.avail_out == 0) {
1861-
ctx->stream.next_out = ctx->buffer;
1862-
len = c->bufferSize - ctx->stream.avail_out;
1863-
1864-
ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len);
1865-
b = apr_bucket_heap_create((char *)ctx->buffer, len,
1866-
NULL, f->c->bucket_alloc);
1867-
APR_BRIGADE_INSERT_TAIL(ctx->bb, b);
1868-
ctx->stream.avail_out = c->bufferSize;
1831+
consume_buffer(ctx, c, c->bufferSize, UPDATE_CRC, ctx->bb);
1832+
18691833
/* Send what we have right now to the next filter. */
18701834
rv = ap_pass_brigade(f->next, ctx->bb);
1835+
apr_brigade_cleanup(ctx->bb);
18711836
if (rv != APR_SUCCESS) {
18721837
return rv;
18731838
}

0 commit comments

Comments
 (0)