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

(-)mod_deflate.c (-86 / +94 lines)
Lines 937-942 Link Here
937
        ctx->bb = apr_brigade_create(r->pool, f->c->bucket_alloc);
937
        ctx->bb = apr_brigade_create(r->pool, f->c->bucket_alloc);
938
        ctx->proc_bb = apr_brigade_create(r->pool, f->c->bucket_alloc);
938
        ctx->proc_bb = apr_brigade_create(r->pool, f->c->bucket_alloc);
939
        ctx->buffer = apr_palloc(r->pool, c->bufferSize);
939
        ctx->buffer = apr_palloc(r->pool, c->bufferSize);
940
        ctx->validation_buffer = NULL;
941
        ctx->validation_buffer_length = 0;
940
942
941
        rv = ap_get_brigade(f->next, ctx->bb, AP_MODE_READBYTES, block, 10);
943
        rv = ap_get_brigade(f->next, ctx->bb, AP_MODE_READBYTES, block, 10);
942
        if (rv != APR_SUCCESS) {
944
        if (rv != APR_SUCCESS) {
Lines 1051-1161 Link Here
1051
                break;
1053
                break;
1052
            }
1054
            }
1053
1055
1054
            /* sanity check - data after completed compressed body and before eos? */
1055
            if (ctx->done) {
1056
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02482)
1057
                              "Encountered extra data after compressed data");
1058
                return APR_EGENERAL;
1059
            }
1060
1061
            /* read */
1056
            /* read */
1062
            apr_bucket_read(bkt, &data, &len, APR_BLOCK_READ);
1057
            apr_bucket_read(bkt, &data, &len, APR_BLOCK_READ);
1063
1058
1064
            /* pass through zlib inflate. */
1059
                if (!ctx->done) {
1065
            ctx->stream.next_in = (unsigned char *)data;
1066
            ctx->stream.avail_in = len;
1067
1060
1068
            zRC = Z_OK;
1061
                    /* pass through zlib inflate. */
1062
                    ctx->stream.next_in = (unsigned char *)data;
1063
                    ctx->stream.avail_in = len;
1069
1064
1070
            while (ctx->stream.avail_in != 0) {
1065
                    zRC = Z_OK;
1071
                if (ctx->stream.avail_out == 0) {
1072
                    apr_bucket *tmp_heap;
1073
                    ctx->stream.next_out = ctx->buffer;
1074
                    len = c->bufferSize - ctx->stream.avail_out;
1075
1066
1076
                    ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len);
1067
                    while (ctx->stream.avail_in != 0) {
1077
                    tmp_heap = apr_bucket_heap_create((char *)ctx->buffer, len,
1068
                         if (ctx->stream.avail_out == 0) {
1078
                                                      NULL, f->c->bucket_alloc);
1069
                              apr_bucket *tmp_heap;
1079
                    APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, tmp_heap);
1070
                              ctx->stream.next_out = ctx->buffer;
1080
                    ctx->stream.avail_out = c->bufferSize;
1071
                              len = c->bufferSize - ctx->stream.avail_out;
1081
                }
1082
1072
1083
                zRC = inflate(&ctx->stream, Z_NO_FLUSH);
1073
                              ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len);
1074
                              tmp_heap = apr_bucket_heap_create((char *)ctx->buffer, len,
1075
                                                                            NULL, f->c->bucket_alloc);
1076
                              APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, tmp_heap);
1077
                              ctx->stream.avail_out = c->bufferSize;
1078
                         }
1084
1079
1085
                if (zRC == Z_STREAM_END) {
1080
                         zRC = inflate(&ctx->stream, Z_NO_FLUSH);
1086
                    break;
1087
                }
1088
1081
1089
                if (zRC != Z_OK) {
1082
                         if (zRC == Z_STREAM_END) {
1090
                    inflateEnd(&ctx->stream);
1083
                              break;
1091
                    ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01392)
1084
                         }
1092
                                  "Zlib error %d inflating data (%s)", zRC,
1093
                                  ctx->stream.msg);
1094
                    return APR_EGENERAL;
1095
                }
1096
            }
1097
            if (zRC == Z_STREAM_END) {
1098
                apr_bucket *tmp_heap;
1099
                apr_size_t avail;
1100
1085
1101
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01393)
1086
                         if (zRC != Z_OK) {
1102
                              "Zlib: Inflated %ld to %ld : URL %s",
1087
                              inflateEnd(&ctx->stream);
1103
                              ctx->stream.total_in, ctx->stream.total_out,
1088
                              ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01392)
1104
                              r->uri);
1089
                                                 "Zlib error %d inflating data (%s)", zRC,
1090
                                                 ctx->stream.msg);
1091
                              return APR_EGENERAL;
1092
                         }
1093
                    }
1094
                    if (zRC == Z_STREAM_END) {
1095
                         apr_bucket *tmp_heap;
1096
                         apr_size_t avail;
1105
1097
1106
                len = c->bufferSize - ctx->stream.avail_out;
1098
                         ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01393)
1099
                                            "Zlib: Inflated %ld to %ld : URL %s",
1100
                                            ctx->stream.total_in, ctx->stream.total_out,
1101
                                            r->uri);
1107
1102
1108
                ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len);
1103
                         len = c->bufferSize - ctx->stream.avail_out;
1109
                tmp_heap = apr_bucket_heap_create((char *)ctx->buffer, len,
1110
                                                  NULL, f->c->bucket_alloc);
1111
                APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, tmp_heap);
1112
                ctx->stream.avail_out = c->bufferSize;
1113
1104
1114
                avail = ctx->stream.avail_in;
1105
                         ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len);
1106
                         tmp_heap = apr_bucket_heap_create((char *)ctx->buffer, len,
1107
                                                                      NULL, f->c->bucket_alloc);
1108
                         APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, tmp_heap);
1109
                         ctx->stream.avail_out = c->bufferSize;
1115
1110
1116
                /* Is the remaining 8 bytes already in the avail stream? */
1111
                         avail = ctx->stream.avail_in;
1117
                if (avail >= 8) {
1112
1118
                    unsigned long compCRC, compLen;
1113
                         /* Is the remaining 8 bytes already in the avail stream? */
1119
                    compCRC = getLong(ctx->stream.next_in);
1114
                         if (avail >= VALIDATION_SIZE) {
1120
                    if (ctx->crc != compCRC) {
1115
                              ctx->validation_buffer = ctx->stream.next_in;
1121
                        inflateEnd(&ctx->stream);
1116
                              ctx->validation_buffer_length = avail;
1122
                        ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01394)
1117
                              len = avail - VALIDATION_SIZE;
1123
                                      "Zlib: CRC error inflating data");
1118
                         }
1124
                        return APR_EGENERAL;
1119
                         else    {     
1120
                             ctx->validation_buffer = apr_pcalloc(f->r->pool, VALIDATION_SIZE);
1121
                             memcpy(ctx->validation_buffer + ctx->validation_buffer_length, ctx->stream.next_in, avail);
1122
                             ctx->validation_buffer_length = avail;
1123
                             len = 0;
1124
                         }
1125
1126
                         inflateEnd(&ctx->stream);
1127
                         ctx->done = 1;
1125
                    }
1128
                    }
1126
                    ctx->stream.next_in += 4;
1127
                    compLen = getLong(ctx->stream.next_in);
1128
                    if (ctx->stream.total_out != compLen) {
1129
                        inflateEnd(&ctx->stream);
1130
                        ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01395)
1131
                                      "Zlib: Length %ld of inflated data does "
1132
                                      "not match expected value %ld",
1133
                                      ctx->stream.total_out, compLen);
1134
                        return APR_EGENERAL;
1135
                    }
1136
                }
1129
                }
1137
                else {
1138
                    /* FIXME: We need to grab the 8 verification bytes
1139
                     * from the wire! */
1140
                    inflateEnd(&ctx->stream);
1141
                    ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01396)
1142
                                  "Verification data not available (bug?)");
1143
                    return APR_EGENERAL;
1144
                }
1145
1130
1146
                inflateEnd(&ctx->stream);
1131
                if (ctx->done)    {
1132
                    
1133
                    /* Check verification bytes */
1134
                    if (ctx->validation_buffer_length)    {
1135
                        /* Did we have trailing data behind the closing 8 bytes? */
1136
                        if (ctx->validation_buffer_length + len > VALIDATION_SIZE)    {
1137
                            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02485)
1138
                                "Encountered extra data after compressed data");
1139
                            return APR_EGENERAL;
1140
                        }
1141
                        if (len)    {
1142
                            memcpy(ctx->validation_buffer + ctx->validation_buffer_length,data,len);
1143
                            ctx->validation_buffer_length += len;
1144
                        }
1145
                    }
1147
1146
1148
                ctx->done = 1;
1147
                    if (ctx->validation_buffer_length == VALIDATION_SIZE)    {
1149
1148
                        unsigned long compCRC, compLen;
1150
                /* Did we have trailing data behind the closing 8 bytes? */
1149
                        compCRC = getLong(ctx->validation_buffer);
1151
                if (avail > 8) {
1150
                        if (ctx->crc != compCRC) {
1152
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02485)
1151
                            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01394)
1153
                                  "Encountered extra data after compressed data");
1152
                                "Zlib: CRC error inflating data");
1154
                    return APR_EGENERAL;
1153
                            return APR_EGENERAL;
1154
                        }
1155
                        ctx->validation_buffer += 4;
1156
                        compLen = getLong(ctx->validation_buffer);
1157
                        if (ctx->stream.total_out != compLen) {
1158
                            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01395)
1159
                                "Zlib: Length %ld of inflated data does "
1160
                                "not match expected value %ld",
1161
                            ctx->stream.total_out, compLen);
1162
                            return APR_EGENERAL;
1163
                        }
1164
                    }
1155
                }
1165
                }
1156
            }
1166
          }
1157
1158
        }
1159
        apr_brigade_cleanup(ctx->bb);
1167
        apr_brigade_cleanup(ctx->bb);
1160
    }
1168
    }
1161
1169

Return to bug 46146