View | Details | Raw Unified | Return to bug 46146
Collapse All | Expand All

(-)modules/filters/mod_deflate.orig (-32 / +103 lines)
Lines 784-795 Link Here
784
        ctx->bb = apr_brigade_create(r->pool, f->c->bucket_alloc);
784
        ctx->bb = apr_brigade_create(r->pool, f->c->bucket_alloc);
785
        ctx->proc_bb = apr_brigade_create(r->pool, f->c->bucket_alloc);
785
        ctx->proc_bb = apr_brigade_create(r->pool, f->c->bucket_alloc);
786
        ctx->buffer = apr_palloc(r->pool, c->bufferSize);
786
        ctx->buffer = apr_palloc(r->pool, c->bufferSize);
787
        ctx->libz_end_func = inflateEnd;
788
        ctx->validation_buffer = NULL;
789
        ctx->validation_buffer_length = 0;
787
790
788
        rv = ap_get_brigade(f->next, ctx->bb, AP_MODE_READBYTES, block, 10);
791
        rv = ap_get_brigade(f->next, ctx->bb, AP_MODE_READBYTES, block, 10);
789
        if (rv != APR_SUCCESS) {
792
        if (rv != APR_SUCCESS) {
790
            return rv;
793
            return rv;
791
        }
794
        }
792
795
796
        /*
797
         * Register a cleanup function to ensure that we cleanup the internal
798
         * libz resources.
799
         */
800
        apr_pool_cleanup_register(r->pool, ctx, deflate_ctx_cleanup,
801
                                  apr_pool_cleanup_null);
802
793
        apr_table_unset(r->headers_in, "Content-Length");
803
        apr_table_unset(r->headers_in, "Content-Length");
794
        apr_table_unset(r->headers_in, "Content-MD5");
804
        apr_table_unset(r->headers_in, "Content-MD5");
795
805
Lines 803-808 Link Here
803
        if (len != 10 ||
813
        if (len != 10 ||
804
            deflate_hdr[0] != deflate_magic[0] ||
814
            deflate_hdr[0] != deflate_magic[0] ||
805
            deflate_hdr[1] != deflate_magic[1]) {
815
            deflate_hdr[1] != deflate_magic[1]) {
816
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
817
                          "Zlib: didn't recieve valid gzip magic bytes");
806
            return APR_EGENERAL;
818
            return APR_EGENERAL;
807
        }
819
        }
808
820
Lines 829-834 Link Here
829
        ctx->stream.avail_out = c->bufferSize;
841
        ctx->stream.avail_out = c->bufferSize;
830
842
831
        apr_brigade_cleanup(ctx->bb);
843
        apr_brigade_cleanup(ctx->bb);
844
        ctx->inflate_init = 1;
832
    }
845
    }
833
846
834
    if (APR_BRIGADE_EMPTY(ctx->proc_bb)) {
847
    if (APR_BRIGADE_EMPTY(ctx->proc_bb)) {
Lines 847-856 Link Here
847
            const char *data;
860
            const char *data;
848
            apr_size_t len;
861
            apr_size_t len;
849
862
850
            /* If we actually see the EOS, that means we screwed up! */
851
            if (APR_BUCKET_IS_EOS(bkt)) {
863
            if (APR_BUCKET_IS_EOS(bkt)) {
864
                apr_bucket *eos;
865
                ap_remove_output_filter(f);
866
                ctx->stream.avail_in = 0;
867
                if (ctx->validation_buffer_length == VALIDATION_SIZE) {
868
                    unsigned long compCRC, compLen;
869
                    compCRC = getLong(ctx->validation_buffer);
870
                    if (ctx->crc != compCRC) {
871
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
872
                                      "Zlib: Checksum of inflated stream invalid: "
873
                                      "%ld != %ld",
874
                                      ctx->crc, compCRC);
875
                        return APR_EGENERAL;
876
                    }
877
                    ctx->validation_buffer += VALIDATION_SIZE / 2;
878
                    compLen = getLong(ctx->validation_buffer);
879
                    if (ctx->stream.total_out != compLen) {
880
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
881
                                      "Zlib: Length of inflated stream invalid: "
882
                                      "%ld != %ld", ctx->stream.total_out,
883
                                      compLen);
884
                        return APR_EGENERAL;
885
                    }
886
                } else if (ctx->inflate_init != -1){
887
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
888
                              "Zlib: Validation bytes not present");
889
                    return APR_EGENERAL;
890
                }
852
                inflateEnd(&ctx->stream);
891
                inflateEnd(&ctx->stream);
853
                return APR_EGENERAL;
892
                ctx->validation_buffer = NULL;
893
                ctx->validation_buffer_length = 0;
894
                /* No need for cleanup any longer */
895
                apr_pool_cleanup_kill(r->pool, ctx, deflate_ctx_cleanup);
896
897
                eos = apr_bucket_eos_create(f->c->bucket_alloc);
898
                APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, eos);
899
    
900
                /*
901
                 * Okay, we've seen the EOS.
902
                 * Time to pass it along down the chain.
903
                 */
904
905
                ctx->inflate_init = -1;
906
                return ap_pass_brigade(f->next, ctx->bb);
854
            }
907
            }
855
908
856
            if (APR_BUCKET_IS_FLUSH(bkt)) {
909
            if (APR_BUCKET_IS_FLUSH(bkt)) {
Lines 885-890 Link Here
885
938
886
            zRC = Z_OK;
939
            zRC = Z_OK;
887
940
941
            if (ctx->validation_buffer) {
942
                if (ctx->validation_buffer_length < VALIDATION_SIZE) {
943
                    apr_size_t copy_size;
944
    
945
                    copy_size = VALIDATION_SIZE - ctx->validation_buffer_length;
946
                    if (copy_size > ctx->stream.avail_in)
947
                        copy_size = ctx->stream.avail_in;
948
                    memcpy(ctx->validation_buffer + ctx->validation_buffer_length,
949
                           ctx->stream.next_in, copy_size);
950
                    /* Saved copy_size bytes */
951
                    ctx->stream.avail_in -= copy_size;
952
                    ctx->validation_buffer_length += copy_size;
953
                }
954
955
                if (ctx->stream.avail_in) {
956
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
957
                                  "Zlib: %d bytes of garbage at the end of "
958
                                  "compressed stream.", ctx->stream.avail_in);
959
                    /*
960
                     * There is nothing worth consuming for zlib left, because it is
961
                     * either garbage data or the data has been copied to the
962
                     * validation buffer (processing validation data is no business
963
                     * for zlib). So set ctx->stream.avail_in to zero to indicate
964
                     * this to the following while loop.
965
                     */
966
                    ctx->stream.avail_in = 0;
967
                }
968
            }
969
888
            while (ctx->stream.avail_in != 0) {
970
            while (ctx->stream.avail_in != 0) {
889
                if (ctx->stream.avail_out == 0) {
971
                if (ctx->stream.avail_out == 0) {
890
                    apr_bucket *tmp_heap;
972
                    apr_bucket *tmp_heap;
Lines 910-916 Link Here
910
                }
992
                }
911
            }
993
            }
912
            if (zRC == Z_STREAM_END) {
994
            if (zRC == Z_STREAM_END) {
913
                apr_bucket *tmp_heap, *eos;
995
                apr_bucket *tmp_heap;
914
996
915
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
997
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
916
                              "Zlib: Inflated %ld to %ld : URL %s",
998
                              "Zlib: Inflated %ld to %ld : URL %s",
Lines 925-960 Link Here
925
                APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, tmp_heap);
1007
                APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, tmp_heap);
926
                ctx->stream.avail_out = c->bufferSize;
1008
                ctx->stream.avail_out = c->bufferSize;
927
1009
928
                /* Is the remaining 8 bytes already in the avail stream? */
1010
                /*
929
                if (ctx->stream.avail_in >= 8) {
1011
                 * We have inflated all data. Now try to capture the
930
                    unsigned long compCRC, compLen;
1012
                 * validation bytes. We may not have them all available
931
                    compCRC = getLong(ctx->stream.next_in);
1013
                 * right now, but capture what is there.
932
                    if (ctx->crc != compCRC) {
1014
                 */
933
                        inflateEnd(&ctx->stream);
1015
                ctx->validation_buffer = apr_pcalloc(f->r->pool,
934
                        return APR_EGENERAL;
1016
                                                     VALIDATION_SIZE);
935
                    }
1017
                if (ctx->stream.avail_in > VALIDATION_SIZE) {
936
                    ctx->stream.next_in += 4;
1018
                    ctx->validation_buffer_length = VALIDATION_SIZE;
937
                    compLen = getLong(ctx->stream.next_in);
938
                    if (ctx->stream.total_out != compLen) {
939
                        inflateEnd(&ctx->stream);
940
                        return APR_EGENERAL;
941
                    }
942
                }
943
                else {
944
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
1019
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
945
                                  "bytes left after Z_STREAM_END bucket:%ld",
1020
                                  "Zlib: %d bytes of garbage at the end of "
946
                                  ctx->stream.avail_in);
1021
                                  "compressed stream.",
947
                    /* FIXME: We need to grab the 8 verification bytes
1022
                                  ctx->stream.avail_in - VALIDATION_SIZE);
948
                     * from the wire! */
1023
                } else if (ctx->stream.avail_in > 0) {
949
                    inflateEnd(&ctx->stream);
1024
                           ctx->validation_buffer_length = ctx->stream.avail_in;
950
                    return APR_EGENERAL;
1025
                }
951
                }
1026
                if (ctx->validation_buffer_length)
952
1027
                    memcpy(ctx->validation_buffer, ctx->stream.next_in,
953
                inflateEnd(&ctx->stream);
1028
                           ctx->validation_buffer_length);
954
955
                eos = apr_bucket_eos_create(f->c->bucket_alloc);
956
                APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, eos);
957
                break;
958
            }
1029
            }
959
1030
960
        }
1031
        }

Return to bug 46146