X-Git-Url: http://www.privoxy.org/gitweb/misc.html?a=blobdiff_plain;f=parsers.c;h=1cb46dfeb5d928087c27599f3057b6294843a40d;hb=b574731be3564ad383b96642877ee66c7e7917fb;hp=69a8fb4bfd8d6c1b200e12107e345362b1333b4e;hpb=73b7af6379688bc06717396e36bfdf55a994af95;p=privoxy.git
diff --git a/parsers.c b/parsers.c
index 69a8fb4b..1cb46dfe 100644
--- a/parsers.c
+++ b/parsers.c
@@ -4,7 +4,7 @@
*
* Purpose : Declares functions to parse/crunch headers and pages.
*
- * Copyright : Written by and Copyright (C) 2001-2020 the
+ * Copyright : Written by and Copyright (C) 2001-2021 the
* Privoxy team. https://www.privoxy.org/
*
* Based on the Internet Junkbuster originally written
@@ -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);
}
@@ -1346,9 +1376,11 @@ jb_err sed_https(struct client_state *csp)
csp->flags |= CSP_FLAG_CLIENT_HEADER_PARSING_DONE;
/*
- * Update the last header which may have changed
- * due to header additions,
+ * Update the https headers list which may have
+ * been modified due to header additions or header
+ * reordering.
*/
+ csp->https_headers->first = csp->headers->first;
csp->https_headers->last = csp->headers->last;
csp->headers->first = headers.first;
@@ -1693,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;
}
@@ -1707,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;
}
@@ -1719,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)
{
@@ -4593,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 == ' ')