@@ -66,7 +66,7 @@ typedef struct deflate_filter_config_t
66
66
int windowSize ;
67
67
int memlevel ;
68
68
int compressionlevel ;
69
- apr_size_t bufferSize ;
69
+ int bufferSize ;
70
70
const char * note_ratio_name ;
71
71
const char * note_input_name ;
72
72
const char * note_output_name ;
@@ -254,7 +254,7 @@ static const char *deflate_set_buffer_size(cmd_parms *cmd, void *dummy,
254
254
return "DeflateBufferSize should be positive" ;
255
255
}
256
256
257
- c -> bufferSize = ( apr_size_t ) n ;
257
+ c -> bufferSize = n ;
258
258
259
259
return NULL ;
260
260
}
@@ -416,35 +416,40 @@ typedef struct deflate_ctx_t
416
416
/* Do update ctx->crc, see comment in flush_libz_buffer */
417
417
#define UPDATE_CRC 1
418
418
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
+
419
441
static int flush_libz_buffer (deflate_ctx * ctx , deflate_filter_config * c ,
420
- struct apr_bucket_alloc_t * bucket_alloc ,
421
442
int (* libz_func )(z_streamp , int ), int flush ,
422
443
int crc )
423
444
{
424
445
int zRC = Z_OK ;
425
446
int done = 0 ;
426
- unsigned int deflate_len ;
427
- apr_bucket * b ;
447
+ int deflate_len ;
428
448
429
449
for (;;) {
430
450
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 );
448
453
}
449
454
450
455
if (done )
@@ -560,6 +565,7 @@ static apr_status_t deflate_out_filter(ap_filter_t *f,
560
565
request_rec * r = f -> r ;
561
566
deflate_ctx * ctx = f -> ctx ;
562
567
int zRC ;
568
+ apr_status_t rv ;
563
569
apr_size_t len = 0 , blen ;
564
570
const char * data ;
565
571
deflate_filter_config * c ;
@@ -891,8 +897,7 @@ static apr_status_t deflate_out_filter(ap_filter_t *f,
891
897
892
898
ctx -> stream .avail_in = 0 ; /* should be zero already anyway */
893
899
/* 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 );
896
901
897
902
buf = apr_palloc (r -> pool , VALIDATION_SIZE );
898
903
putLong ((unsigned char * )& buf [0 ], ctx -> crc );
@@ -935,6 +940,10 @@ static apr_status_t deflate_out_filter(ap_filter_t *f,
935
940
}
936
941
937
942
deflateEnd (& ctx -> stream );
943
+
944
+ /* We've ended the libz stream, so remove ourselves. */
945
+ ap_remove_output_filter (f );
946
+
938
947
/* No need for cleanup any longer */
939
948
apr_pool_cleanup_kill (r -> pool , ctx , deflate_ctx_cleanup );
940
949
@@ -945,15 +954,15 @@ static apr_status_t deflate_out_filter(ap_filter_t *f,
945
954
/* Okay, we've seen the EOS.
946
955
* Time to pass it along down the chain.
947
956
*/
948
- return ap_pass_brigade (f -> next , ctx -> bb );
957
+ rv = ap_pass_brigade (f -> next , ctx -> bb );
958
+ apr_brigade_cleanup (ctx -> bb );
959
+ return rv ;
949
960
}
950
961
951
962
if (APR_BUCKET_IS_FLUSH (e )) {
952
- apr_status_t rv ;
953
-
954
963
/* 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 );
964
+ zRC = flush_libz_buffer (ctx , c , deflate , Z_SYNC_FLUSH ,
965
+ NO_UPDATE_CRC );
957
966
if (zRC != Z_OK ) {
958
967
ap_log_rerror (APLOG_MARK , APLOG_ERR , 0 , r , APLOGNO (01385 )
959
968
"Zlib error %d flushing zlib output buffer (%s)" ,
@@ -965,6 +974,7 @@ static apr_status_t deflate_out_filter(ap_filter_t *f,
965
974
APR_BUCKET_REMOVE (e );
966
975
APR_BRIGADE_INSERT_TAIL (ctx -> bb , e );
967
976
rv = ap_pass_brigade (f -> next , ctx -> bb );
977
+ apr_brigade_cleanup (ctx -> bb );
968
978
if (rv != APR_SUCCESS ) {
969
979
return rv ;
970
980
}
@@ -982,7 +992,12 @@ static apr_status_t deflate_out_filter(ap_filter_t *f,
982
992
}
983
993
984
994
/* read */
985
- apr_bucket_read (e , & data , & len , APR_BLOCK_READ );
995
+ rv = apr_bucket_read (e , & data , & len , APR_BLOCK_READ );
996
+ if (rv ) {
997
+ ap_log_rerror (APLOG_MARK , APLOG_ERR , rv , r , APLOGNO (10298 )
998
+ "failed reading from %s bucket" , e -> type -> name );
999
+ return rv ;
1000
+ }
986
1001
if (!len ) {
987
1002
apr_bucket_delete (e );
988
1003
continue ;
@@ -999,21 +1014,15 @@ static apr_status_t deflate_out_filter(ap_filter_t *f,
999
1014
ctx -> stream .next_in = (unsigned char * )data ; /* We just lost const-ness,
1000
1015
* but we'll just have to
1001
1016
* trust zlib */
1002
- ctx -> stream .avail_in = len ;
1017
+ ctx -> stream .avail_in = ( int ) len ;
1003
1018
1004
1019
while (ctx -> stream .avail_in != 0 ) {
1005
1020
if (ctx -> stream .avail_out == 0 ) {
1006
- apr_status_t rv ;
1021
+ consume_buffer ( ctx , c , c -> bufferSize , NO_UPDATE_CRC , ctx -> bb ) ;
1007
1022
1008
- ctx -> stream .next_out = ctx -> buffer ;
1009
- len = c -> bufferSize - ctx -> stream .avail_out ;
1010
-
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 ;
1015
1023
/* Send what we have right now to the next filter. */
1016
1024
rv = ap_pass_brigade (f -> next , ctx -> bb );
1025
+ apr_brigade_cleanup (ctx -> bb );
1017
1026
if (rv != APR_SUCCESS ) {
1018
1027
return rv ;
1019
1028
}
@@ -1310,44 +1319,40 @@ static apr_status_t deflate_in_filter(ap_filter_t *f,
1310
1319
if (APR_BUCKET_IS_FLUSH (bkt )) {
1311
1320
apr_bucket * tmp_b ;
1312
1321
1313
- ctx -> inflate_total += ctx -> stream .avail_out ;
1314
- zRC = inflate (& (ctx -> stream ), Z_SYNC_FLUSH );
1315
- ctx -> inflate_total -= ctx -> stream .avail_out ;
1316
- if (zRC != Z_OK ) {
1317
- inflateEnd (& ctx -> stream );
1318
- ap_log_rerror (APLOG_MARK , APLOG_WARNING , 0 , r , APLOGNO (01391 )
1319
- "Zlib error %d inflating data (%s)" , zRC ,
1320
- ctx -> stream .msg );
1321
- return APR_EGENERAL ;
1322
- }
1322
+ if (!ctx -> done ) {
1323
+ ctx -> inflate_total += ctx -> stream .avail_out ;
1324
+ zRC = inflate (& (ctx -> stream ), Z_SYNC_FLUSH );
1325
+ ctx -> inflate_total -= ctx -> stream .avail_out ;
1326
+ if (zRC != Z_OK ) {
1327
+ inflateEnd (& ctx -> stream );
1328
+ ap_log_rerror (APLOG_MARK , APLOG_WARNING , 0 , r , APLOGNO (01391 )
1329
+ "Zlib error %d inflating data (%s)" , zRC ,
1330
+ ctx -> stream .msg );
1331
+ return APR_EGENERAL ;
1332
+ }
1323
1333
1324
- if (inflate_limit && ctx -> inflate_total > inflate_limit ) {
1325
- inflateEnd (& ctx -> stream );
1326
- ap_log_rerror (APLOG_MARK , APLOG_WARNING , 0 , r , APLOGNO (02647 )
1327
- "Inflated content length of %" APR_OFF_T_FMT
1328
- " is larger than the configured limit"
1329
- " of %" APR_OFF_T_FMT ,
1330
- ctx -> inflate_total , inflate_limit );
1331
- return APR_ENOSPC ;
1332
- }
1333
-
1334
- if (!check_ratio (r , ctx , dc )) {
1335
- inflateEnd (& ctx -> stream );
1336
- ap_log_rerror (APLOG_MARK , APLOG_WARNING , 0 , r , APLOGNO (02805 )
1337
- "Inflated content ratio is larger than the "
1338
- "configured limit %i by %i time(s)" ,
1339
- dc -> ratio_limit , dc -> ratio_burst );
1340
- return APR_EINVAL ;
1341
- }
1334
+ if (inflate_limit && ctx -> inflate_total > inflate_limit ) {
1335
+ inflateEnd (& ctx -> stream );
1336
+ ap_log_rerror (APLOG_MARK , APLOG_WARNING , 0 , r , APLOGNO (02647 )
1337
+ "Inflated content length of %" APR_OFF_T_FMT
1338
+ " is larger than the configured limit"
1339
+ " of %" APR_OFF_T_FMT ,
1340
+ ctx -> inflate_total , inflate_limit );
1341
+ return APR_ENOSPC ;
1342
+ }
1342
1343
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 );
1344
+ if (!check_ratio (r , ctx , dc )) {
1345
+ inflateEnd (& ctx -> stream );
1346
+ ap_log_rerror (APLOG_MARK , APLOG_WARNING , 0 , r , APLOGNO (02805 )
1347
+ "Inflated content ratio is larger than the "
1348
+ "configured limit %i by %i time(s)" ,
1349
+ dc -> ratio_limit , dc -> ratio_burst );
1350
+ return APR_EINVAL ;
1351
+ }
1348
1352
1349
- ctx -> stream .next_out = ctx -> buffer ;
1350
- ctx -> stream .avail_out = c -> bufferSize ;
1353
+ consume_buffer (ctx , c , c -> bufferSize - ctx -> stream .avail_out ,
1354
+ UPDATE_CRC , ctx -> proc_bb );
1355
+ }
1351
1356
1352
1357
/* Flush everything so far in the returning brigade, but continue
1353
1358
* reading should EOS/more follow (don't lose them).
@@ -1393,16 +1398,8 @@ static apr_status_t deflate_in_filter(ap_filter_t *f,
1393
1398
if (!ctx -> validation_buffer ) {
1394
1399
while (ctx -> stream .avail_in != 0 ) {
1395
1400
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 ;
1401
+ consume_buffer (ctx , c , c -> bufferSize , UPDATE_CRC ,
1402
+ ctx -> proc_bb );
1406
1403
}
1407
1404
1408
1405
ctx -> inflate_total += ctx -> stream .avail_out ;
@@ -1445,7 +1442,6 @@ static apr_status_t deflate_in_filter(ap_filter_t *f,
1445
1442
}
1446
1443
1447
1444
if (ctx -> validation_buffer ) {
1448
- apr_bucket * tmp_heap ;
1449
1445
apr_size_t avail , valid ;
1450
1446
unsigned char * buf = ctx -> validation_buffer ;
1451
1447
@@ -1474,13 +1470,8 @@ static apr_status_t deflate_in_filter(ap_filter_t *f,
1474
1470
(apr_uint64_t )ctx -> stream .total_in ,
1475
1471
(apr_uint64_t )ctx -> stream .total_out , r -> uri );
1476
1472
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 ;
1473
+ consume_buffer (ctx , c , c -> bufferSize - ctx -> stream .avail_out ,
1474
+ UPDATE_CRC , ctx -> proc_bb );
1484
1475
1485
1476
{
1486
1477
unsigned long compCRC , compLen ;
@@ -1526,16 +1517,8 @@ static apr_status_t deflate_in_filter(ap_filter_t *f,
1526
1517
if (block == APR_BLOCK_READ &&
1527
1518
APR_BRIGADE_EMPTY (ctx -> proc_bb ) &&
1528
1519
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 ;
1520
+ consume_buffer (ctx , c , c -> bufferSize - ctx -> stream .avail_out ,
1521
+ UPDATE_CRC , ctx -> proc_bb );
1539
1522
}
1540
1523
1541
1524
if (!APR_BRIGADE_EMPTY (ctx -> proc_bb )) {
@@ -1651,7 +1634,6 @@ static apr_status_t inflate_out_filter(ap_filter_t *f,
1651
1634
while (!APR_BRIGADE_EMPTY (bb ))
1652
1635
{
1653
1636
const char * data ;
1654
- apr_bucket * b ;
1655
1637
apr_size_t len ;
1656
1638
1657
1639
e = APR_BRIGADE_FIRST (bb );
@@ -1673,8 +1655,7 @@ static apr_status_t inflate_out_filter(ap_filter_t *f,
1673
1655
* fails, whereas in the deflate case you can empty a filled output
1674
1656
* buffer and call it again until no more output can be created.
1675
1657
*/
1676
- flush_libz_buffer (ctx , c , f -> c -> bucket_alloc , inflate , Z_SYNC_FLUSH ,
1677
- UPDATE_CRC );
1658
+ flush_libz_buffer (ctx , c , inflate , Z_SYNC_FLUSH , UPDATE_CRC );
1678
1659
ap_log_rerror (APLOG_MARK , APLOG_DEBUG , 0 , r , APLOGNO (01398 )
1679
1660
"Zlib: Inflated %" APR_UINT64_T_FMT
1680
1661
" to %" APR_UINT64_T_FMT " : URL %s" ,
@@ -1716,15 +1697,14 @@ static apr_status_t inflate_out_filter(ap_filter_t *f,
1716
1697
* Okay, we've seen the EOS.
1717
1698
* Time to pass it along down the chain.
1718
1699
*/
1719
- return ap_pass_brigade (f -> next , ctx -> bb );
1700
+ rv = ap_pass_brigade (f -> next , ctx -> bb );
1701
+ apr_brigade_cleanup (ctx -> bb );
1702
+ return rv ;
1720
1703
}
1721
1704
1722
1705
if (APR_BUCKET_IS_FLUSH (e )) {
1723
- apr_status_t rv ;
1724
-
1725
1706
/* 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 );
1707
+ zRC = flush_libz_buffer (ctx , c , inflate , Z_SYNC_FLUSH , UPDATE_CRC );
1728
1708
if (zRC == Z_STREAM_END ) {
1729
1709
if (ctx -> validation_buffer == NULL ) {
1730
1710
ctx -> validation_buffer = apr_pcalloc (f -> r -> pool ,
@@ -1742,6 +1722,7 @@ static apr_status_t inflate_out_filter(ap_filter_t *f,
1742
1722
APR_BUCKET_REMOVE (e );
1743
1723
APR_BRIGADE_INSERT_TAIL (ctx -> bb , e );
1744
1724
rv = ap_pass_brigade (f -> next , ctx -> bb );
1725
+ apr_brigade_cleanup (ctx -> bb );
1745
1726
if (rv != APR_SUCCESS ) {
1746
1727
return rv ;
1747
1728
}
@@ -1858,16 +1839,11 @@ static apr_status_t inflate_out_filter(ap_filter_t *f,
1858
1839
1859
1840
while (ctx -> stream .avail_in != 0 ) {
1860
1841
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 ;
1842
+ consume_buffer (ctx , c , c -> bufferSize , UPDATE_CRC , ctx -> bb );
1843
+
1869
1844
/* Send what we have right now to the next filter. */
1870
1845
rv = ap_pass_brigade (f -> next , ctx -> bb );
1846
+ apr_brigade_cleanup (ctx -> bb );
1871
1847
if (rv != APR_SUCCESS ) {
1872
1848
return rv ;
1873
1849
}
@@ -1882,6 +1858,7 @@ static apr_status_t inflate_out_filter(ap_filter_t *f,
1882
1858
return APR_EGENERAL ;
1883
1859
}
1884
1860
1861
+ /* Don't check length limits on inflate_out */
1885
1862
if (!check_ratio (r , ctx , dc )) {
1886
1863
ap_log_rerror (APLOG_MARK , APLOG_WARNING , 0 , r , APLOGNO (02650 )
1887
1864
"Inflated content ratio is larger than the "
0 commit comments