X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=blobdiff_plain;f=parsers.c;h=c1d4d42e82c241b69f558356626394c01b6b2061;hp=eed559aa163f89a010cd950ae569d7c5c6a452f2;hb=6832f3ddf1642bdc302f307d744dc66931cd5c4f;hpb=a518dea1e45ce14ed5d0e5d1a23de2e8f9c3f5f5 diff --git a/parsers.c b/parsers.c index eed559aa..c1d4d42e 100644 --- a/parsers.c +++ b/parsers.c @@ -1,11 +1,10 @@ -const char parsers_rcs[] = "$Id: parsers.c,v 1.299 2015/03/27 12:39:44 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/parsers.c,v $ * * Purpose : Declares functions to parse/crunch headers and pages. * - * Copyright : Written by and Copyright (C) 2001-2014 the + * Copyright : Written by and Copyright (C) 2001-2017 the * Privoxy team. http://www.privoxy.org/ * * Based on the Internet Junkbuster originally written @@ -90,8 +89,6 @@ const char parsers_rcs[] = "$Id: parsers.c,v 1.299 2015/03/27 12:39:44 fabiankei #include "strptime.h" #endif -const char parsers_h_rcs[] = PARSERS_H_VERSION; - static char *get_header_line(struct iob *iob); static jb_err scan_headers(struct client_state *csp); static jb_err header_tagger(struct client_state *csp, char *header); @@ -387,7 +384,7 @@ jb_err add_to_iob(struct iob *iob, const size_t buffer_limit, char *src, long n) void clear_iob(struct iob *iob) { free(iob->buf); - memset(iob, '\0', sizeof(*iob));; + memset(iob, '\0', sizeof(*iob)); } @@ -421,8 +418,13 @@ jb_err decompress_iob(struct client_state *csp) int status; /* return status of the inflate() call */ z_stream zstr; /* used by calls to zlib */ +#ifdef FUZZ + assert(csp->iob->cur - csp->iob->buf >= 0); + assert(csp->iob->eod - csp->iob->cur >= 0); +#else assert(csp->iob->cur - csp->iob->buf > 0); assert(csp->iob->eod - csp->iob->cur > 0); +#endif bufsize = csp->iob->size; skip_size = (size_t)(csp->iob->cur - csp->iob->buf); @@ -718,7 +720,7 @@ jb_err decompress_iob(struct client_state *csp) * Make sure the new uncompressed iob obeys some minimal * consistency conditions. */ - if ((csp->iob->buf < csp->iob->cur) + if ((csp->iob->buf <= csp->iob->cur) && (csp->iob->cur <= csp->iob->eod) && (csp->iob->eod <= csp->iob->buf + csp->iob->size)) { @@ -1811,7 +1813,9 @@ static jb_err client_keep_alive(struct client_state *csp, char **header) static jb_err get_content_length(const char *header_value, unsigned long long *length) { #ifdef _WIN32 - assert(sizeof(unsigned long long) > 4); +#if SIZEOF_LONG_LONG < 8 +#error sizeof(unsigned long long) too small +#endif if (1 != sscanf(header_value, "%I64u", length)) #else if (1 != sscanf(header_value, "%llu", length)) @@ -2372,8 +2376,7 @@ static jb_err server_content_encoding(struct client_state *csp, char **header) /* * Log a warning if the user expects the content to be filtered. */ - if ((csp->rlist != NULL) && - (!list_is_empty(csp->action->multi[ACTION_MULTI_FILTER]))) + if (content_filters_enabled(csp->action)) { log_error(LOG_LEVEL_INFO, "Compressed content detected, content filtering disabled. " @@ -3287,6 +3290,13 @@ static jb_err client_host(struct client_state *csp, char **header) { char *p, *q; + if (strlen(*header) < 7) + { + log_error(LOG_LEVEL_HEADER, "Removing empty Host header"); + freez(*header); + return JB_ERR_OK; + } + if (!csp->http->hostport || (*csp->http->hostport == '*') || *csp->http->hostport == ' ' || *csp->http->hostport == '\0') { @@ -3600,9 +3610,8 @@ static jb_err client_host_adder(struct client_state *csp) if (!csp->http->hostport || !*(csp->http->hostport)) { - /* XXX: When does this happen and why is it OK? */ - log_error(LOG_LEVEL_INFO, "Weirdness in client_host_adder detected and ignored."); - return JB_ERR_OK; + log_error(LOG_LEVEL_ERROR, "Destination host unknown."); + return JB_ERR_PARSE; } /* @@ -3795,7 +3804,8 @@ static jb_err server_proxy_connection_adder(struct client_state *csp) * Function : client_connection_header_adder * * Description : Adds a proper "Connection:" header to csp->headers - * unless the header was already present. Called from `sed'. + * unless the header was already present or it's a + * CONNECT request. Called from `sed'. * * Parameters : * 1 : csp = Current client state (buffers, headers, etc...) @@ -3814,10 +3824,20 @@ static jb_err client_connection_header_adder(struct client_state *csp) return JB_ERR_OK; } + /* + * In case of CONNECT requests "Connection: close" is implied, + * but actually setting the header has been reported to cause + * problems with some forwarding proxies that close the + * connection prematurely. + */ + if (csp->http->ssl != 0) + { + return JB_ERR_OK; + } + #ifdef FEATURE_CONNECTION_KEEP_ALIVE if ((csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_KEEP_ALIVE) && !(csp->flags & CSP_FLAG_SERVER_SOCKET_TAINTED) - && (csp->http->ssl == 0) && !strcmpic(csp->http->ver, "HTTP/1.1")) { csp->flags |= CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE; @@ -4308,7 +4328,13 @@ static jb_err parse_header_time(const char *header_time, time_t *result) time_t result2; tm = gmtime(result); - strftime(recreated_date, sizeof(recreated_date), time_formats[i], tm); + if (!strftime(recreated_date, sizeof(recreated_date), + time_formats[i], tm)) + { + log_error(LOG_LEVEL_ERROR, "Failed to recreate date '%s' with '%s'.", + header_time, time_formats[i]); + continue; + } memset(&gmt, 0, sizeof(gmt)); if (NULL == strptime(recreated_date, time_formats[i], &gmt)) { @@ -4442,9 +4468,26 @@ jb_err get_destination_from_headers(const struct list *headers, struct http_requ return JB_ERR_MEMORY; } - log_error(LOG_LEVEL_HEADER, "Destination extracted from \"Host:\" header. New request URL: %s", + log_error(LOG_LEVEL_HEADER, + "Destination extracted from \"Host\" header. New request URL: %s", http->url); + /* + * Regenerate request line in "proxy format" + * to make rewrites more convenient. + */ + assert(http->cmd != NULL); + freez(http->cmd); + http->cmd = strdup_or_die(http->gpc); + string_append(&http->cmd, " "); + string_append(&http->cmd, http->url); + string_append(&http->cmd, " "); + string_append(&http->cmd, http->ver); + if (http->cmd == NULL) + { + return JB_ERR_MEMORY; + } + return JB_ERR_OK; } @@ -4600,7 +4643,14 @@ static jb_err handle_conditional_hide_referrer_parameter(char **header, static void create_content_length_header(unsigned long long content_length, char *header, size_t buffer_length) { +#ifdef _WIN32 +#if SIZEOF_LONG_LONG < 8 +#error sizeof(unsigned long long) too small +#endif + snprintf(header, buffer_length, "Content-Length: %I64u", content_length); +#else snprintf(header, buffer_length, "Content-Length: %llu", content_length); +#endif }