X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=blobdiff_plain;f=parsers.c;h=1cb46dfeb5d928087c27599f3057b6294843a40d;hp=d63647d8c03b8d179a0a4fcf076ebe335da226f2;hb=HEAD;hpb=4398286ec2297fdbb7e1faab3e37d2c3ea43e8c8 diff --git a/parsers.c b/parsers.c index d63647d8..1cb46dfe 100644 --- a/parsers.c +++ b/parsers.c @@ -540,7 +540,7 @@ jb_err decompress_iob(struct client_state *csp) cur = csp->iob->cur; - if (bufsize < (size_t)10) + if (old_size < (size_t)10) { /* * This is to protect the parsing of gzipped data, @@ -577,7 +577,8 @@ jb_err decompress_iob(struct client_state *csp) || ((*cur++ & 0xff) != GZIP_IDENTIFIER_2) || (*cur++ != Z_DEFLATED)) { - log_error(LOG_LEVEL_ERROR, "Invalid gzip header when decompressing"); + log_error(LOG_LEVEL_ERROR, + "Invalid gzip header when decompressing."); return JB_ERR_COMPRESS; } else @@ -586,7 +587,8 @@ jb_err decompress_iob(struct client_state *csp) if (flags & GZIP_FLAG_RESERVED_BITS) { /* The gzip header has reserved bits set; bail out. */ - log_error(LOG_LEVEL_ERROR, "Invalid gzip header flags when decompressing"); + log_error(LOG_LEVEL_ERROR, + "Invalid gzip header flags when decompressing."); return JB_ERR_COMPRESS; } @@ -606,8 +608,16 @@ jb_err decompress_iob(struct client_state *csp) * XXX: this code is untested and should probably be removed. */ int skip_bytes; + + if (cur + 2 >= csp->iob->eod) + { + log_error(LOG_LEVEL_ERROR, + "gzip extra field flag set but insufficient data available."); + return JB_ERR_COMPRESS; + } + skip_bytes = *cur++; - skip_bytes += *cur++ << 8; + skip_bytes += (unsigned char)*cur++ << 8; /* * The number of bytes to skip should be positive @@ -616,12 +626,14 @@ jb_err decompress_iob(struct client_state *csp) if ((skip_bytes < 0) || (skip_bytes >= (csp->iob->eod - cur))) { log_error(LOG_LEVEL_ERROR, - "Unreasonable amount of bytes to skip (%d). Stopping decompression", + "Unreasonable amount of bytes to skip (%d). " + "Stopping decompression.", skip_bytes); return JB_ERR_COMPRESS; } log_error(LOG_LEVEL_INFO, - "Skipping %d bytes for gzip compression. Does this sound right?", + "Skipping %d bytes for gzip compression. " + "Does this sound right?", skip_bytes); cur += skip_bytes; } @@ -630,14 +642,14 @@ jb_err decompress_iob(struct client_state *csp) if (flags & GZIP_FLAG_FILE_NAME) { /* A null-terminated string is supposed to follow. */ - while (*cur++ && (cur < csp->iob->eod)); + while ((cur < csp->iob->eod) && *cur++); } /* Skip the comment if necessary. */ if (flags & GZIP_FLAG_COMMENT) { /* A null-terminated string is supposed to follow. */ - while (*cur++ && (cur < csp->iob->eod)); + while ((cur < csp->iob->eod) && *cur++); } /* Skip the CRC if necessary. */ @@ -681,7 +693,7 @@ jb_err decompress_iob(struct client_state *csp) else { log_error(LOG_LEVEL_ERROR, - "Unable to determine compression format for decompression"); + "Unable to determine compression format for decompression."); return JB_ERR_COMPRESS; } @@ -698,19 +710,19 @@ jb_err decompress_iob(struct client_state *csp) */ if (inflateInit2(&zstr, -MAX_WBITS) != Z_OK) { - log_error(LOG_LEVEL_ERROR, "Error initializing decompression"); + log_error(LOG_LEVEL_ERROR, "Error initializing decompression."); return JB_ERR_COMPRESS; } /* * Next, we allocate new storage for the inflated data. * We don't modify the existing iob yet, so in case there - * is error in decompression we can recover gracefully. + * is an error in decompression we can recover gracefully. */ buf = zalloc(bufsize); if (NULL == buf) { - log_error(LOG_LEVEL_ERROR, "Out of memory decompressing iob"); + log_error(LOG_LEVEL_ERROR, "Out of memory decompressing iob."); return JB_ERR_MEMORY; } @@ -746,7 +758,8 @@ jb_err decompress_iob(struct client_state *csp) */ if (bufsize >= csp->config->buffer_limit) { - log_error(LOG_LEVEL_ERROR, "Buffer limit reached while decompressing iob"); + log_error(LOG_LEVEL_ERROR, + "Buffer limit reached while decompressing iob."); freez(buf); inflateEnd(&zstr); return JB_ERR_MEMORY; @@ -765,15 +778,17 @@ jb_err decompress_iob(struct client_state *csp) tmpbuf = realloc(buf, bufsize); if (NULL == tmpbuf) { - log_error(LOG_LEVEL_ERROR, "Out of memory decompressing iob"); + log_error(LOG_LEVEL_ERROR, + "Out of memory decompressing iob."); freez(buf); inflateEnd(&zstr); return JB_ERR_MEMORY; } else { +#ifndef NDEBUG char *oldnext_out = (char *)zstr.next_out; - +#endif /* * Update the fields for inflate() to use the new * buffer, which may be in a location different from @@ -818,6 +833,7 @@ jb_err decompress_iob(struct client_state *csp) log_error(LOG_LEVEL_ERROR, "Unexpected error while decompressing to the buffer (iob): %s", zstr.msg); + freez(buf); return JB_ERR_COMPRESS; } @@ -859,7 +875,8 @@ jb_err decompress_iob(struct client_state *csp) else { /* It seems that zlib did something weird. */ - log_error(LOG_LEVEL_ERROR, "Inconsistent buffer after decompression"); + log_error(LOG_LEVEL_ERROR, + "Inconsistent buffer after decompression."); return JB_ERR_COMPRESS; } @@ -1211,8 +1228,8 @@ static void enforce_header_order(struct list *headers, const struct list *ordere } list_remove_all(headers); - list_duplicate(headers, new_headers); - list_remove_all(new_headers); + headers->first = new_headers->first; + headers->last = new_headers->last; return; } @@ -1284,6 +1301,17 @@ jb_err sed(struct client_state *csp, int filter_server_headers) v++; } + if (filter_server_headers && + (csp->flags & CSP_FLAG_SERVER_CONTENT_LENGTH_SET) && + (csp->flags & CSP_FLAG_CHUNKED)) + { + /* RFC 2616 4.4 3 */ + log_error(LOG_LEVEL_HEADER, "Ignoring the Content-Length header " + "sent by the server as the response is chunk-encoded."); + csp->flags &= ~CSP_FLAG_CONTENT_LENGTH_SET; + csp->expected_content_length = 0; + } + /* place additional headers on the csp->headers list */ while ((err == JB_ERR_OK) && (*f)) { @@ -1291,7 +1319,9 @@ jb_err sed(struct client_state *csp, int filter_server_headers) f++; } - if (!filter_server_headers && !list_is_empty(csp->config->ordered_client_headers)) + if (!filter_server_headers && + !list_is_empty(csp->config->ordered_client_headers) && + csp->headers->first->str != NULL) { enforce_header_order(csp->headers, csp->config->ordered_client_headers); } @@ -1695,7 +1725,8 @@ static jb_err filter_header(struct client_state *csp, char **header) if (NULL == joblist) { - log_error(LOG_LEVEL_RE_FILTER, "Filter %s has empty joblist. Nothing to do.", b->name); + log_error(LOG_LEVEL_RE_FILTER, + "Filter %s has empty joblist. Nothing to do.", b->name); continue; } @@ -1709,7 +1740,8 @@ static jb_err filter_header(struct client_state *csp, char **header) if (0 < matches) { current_hits += matches; - log_error(LOG_LEVEL_HEADER, "Transforming \"%s\" to \"%s\"", *header, newheader); + log_error(LOG_LEVEL_HEADER, + "Transforming \"%s\" to \"%s\"", *header, newheader); freez(*header); *header = newheader; } @@ -1721,7 +1753,8 @@ static jb_err filter_header(struct client_state *csp, char **header) else { /* RegEx failure */ - log_error(LOG_LEVEL_ERROR, "Filtering \'%s\' with \'%s\' didn't work out: %s", + log_error(LOG_LEVEL_ERROR, + "Filtering \'%s\' with \'%s\' didn't work out: %s", *header, b->name, pcrs_strerror(matches)); if (newheader != NULL) { @@ -4595,7 +4628,10 @@ static jb_err parse_time_header(const char *header, time_t *result) * through sed() which requires a header name followed by * a colon. */ - assert(header_time != NULL); + if (header_time == NULL) + { + return JB_ERR_PARSE; + } header_time++; if (*header_time == ' ')