X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=blobdiff_plain;f=filters.c;h=5ca6b996a4d80017bbce3430d426643450dece2c;hp=39946389b518e5b512a60eba158a8c44fd5fabce;hb=83a4ca758c4dccd313f23f9d736f43c34e16e08a;hpb=38a3bb7f642b091a8830b75fe0c8b514209b6175 diff --git a/filters.c b/filters.c index 39946389..5ca6b996 100644 --- a/filters.c +++ b/filters.c @@ -1,19 +1,11 @@ -const char filters_rcs[] = "$Id: filters.c,v 1.155 2011/11/06 11:36:42 fabiankeil Exp $"; +const char filters_rcs[] = "$Id: filters.c,v 1.163 2011/12/26 17:03:08 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/filters.c,v $ * * Purpose : Declares functions to parse/crunch headers and pages. - * Functions declared include: - * `acl_addr', `add_stats', `block_acl', `block_imageurl', - * `block_url', `url_actions', `domain_split', - * `filter_popups', `forward_url', 'redirect_url', - * `ij_untrusted_url', `intercept_url', `pcrs_filter_respose', - * `ijb_send_banner', `trust_url', `gif_deanimate_response', - * `execute_single_pcrs_command', `rewrite_url', - * `get_last_url' - * - * Copyright : Written by and Copyright (C) 2001-2010 the + * + * Copyright : Written by and Copyright (C) 2001-2011 the * Privoxy team. http://www.privoxy.org/ * * Based on the Internet Junkbuster originally written @@ -78,11 +70,6 @@ const char filters_rcs[] = "$Id: filters.c,v 1.155 2011/11/06 11:36:42 fabiankei #include "urlmatch.h" #include "loaders.h" -#ifdef HAVE_STRTOK -/* Only used for locks */ -#include "jcc.h" -#endif /* def HAVE_STRTOK */ - #ifdef _WIN32 #include "win32.h" #endif @@ -1110,73 +1097,78 @@ char *get_last_url(char *subject, const char *redirect_mode) return NULL; } - if (0 == strcmpic(redirect_mode, "check-decoded-url")) + if (0 == strcmpic(redirect_mode, "check-decoded-url") && strchr(subject, '%')) { log_error(LOG_LEVEL_REDIRECTS, "Checking \"%s\" for encoded redirects.", subject); -#if defined(MUTEX_LOCKS_AVAILABLE) && defined(HAVE_STRTOK) /* * Check each parameter in the URL separately. * Sectionize the URL at "?" and "&", - * then URL-decode each component, + * go backwards through the segments, URL-decode them * and look for a URL in the decoded result. - * Keep the last one we spot. + * Stop the search after the first match. + */ + char *url_segment = NULL; + /* + * XXX: This estimate is guaranteed to be high enough as we + * let ssplit() ignore empty fields, but also a bit wasteful. */ - char *found = NULL; + size_t max_segments = strlen(subject) / 2; + char **url_segments = malloc(max_segments * sizeof(char *)); + int segments; + + if (NULL == url_segments) + { + log_error(LOG_LEVEL_ERROR, "Out of memory while decoding URL: %s", new_url); + freez(subject); + return NULL; + } + + segments = ssplit(subject, "?&", url_segments, max_segments, 1, 1); - privoxy_mutex_lock(&strtok_mutex); - char *token = strtok(subject, "?&"); - while (token) + while (segments-- > 0) { - char *dtoken = url_decode(token); + char *dtoken = url_decode(url_segments[segments]); if (NULL == dtoken) { - log_error(LOG_LEVEL_ERROR, "Unable to decode \"%s\".", token); + log_error(LOG_LEVEL_ERROR, "Unable to decode \"%s\".", url_segments[segments]); continue; } - char *http_url = strstr(dtoken, "http://"); - char *https_url = strstr(dtoken, "https://"); - char *last_url = (http_url && https_url - ? (http_url < https_url ? http_url : https_url) - : (http_url ? http_url : https_url)); - if (last_url) + url_segment = strstr(dtoken, "http://"); + if (NULL == url_segment) { - freez(found); - found = strdup(last_url); - if (found == NULL) + url_segment = strstr(dtoken, "https://"); + } + if (NULL != url_segment) + { + url_segment = strdup(url_segment); + freez(dtoken); + if (url_segment == NULL) { log_error(LOG_LEVEL_ERROR, "Out of memory while searching for redirects."); - privoxy_mutex_unlock(&strtok_mutex); return NULL; } + break; } freez(dtoken); - token = strtok(NULL, "?&"); } - privoxy_mutex_unlock(&strtok_mutex); freez(subject); + freez(url_segments); - return found; -#else - new_url = url_decode(subject); - if (new_url != NULL) + if (url_segment == NULL) { - freez(subject); - subject = new_url; - } - else - { - log_error(LOG_LEVEL_ERROR, "Unable to decode \"%s\".", subject); + return NULL; } -#endif /* defined(MUTEX_LOCKS_AVAILABLE) && defined(HAVE_STRTOK) */ + subject = url_segment; + } + else + { + /* Look for a URL inside this one, without decoding anything. */ + log_error(LOG_LEVEL_REDIRECTS, + "Checking \"%s\" for unencoded redirects.", subject); } - - /* Else, just look for a URL inside this one, without decoding anything. */ - - log_error(LOG_LEVEL_REDIRECTS, - "Checking \"%s\" for unencoded redirects.", subject); /* * Find the last URL encoded in the request @@ -1320,6 +1312,7 @@ struct http_response *redirect_url(struct client_state *csp) return cgi_error_memory(); } new_url = encoded_url; + assert(FALSE == url_requires_percent_encoding(new_url)); } if (0 == strcmpic(new_url, csp->http->url)) @@ -1853,19 +1846,15 @@ static jb_err remove_chunked_transfer_coding(char *buffer, size_t *size) return JB_ERR_PARSE; } - if ((newsize += chunksize) >= *size) + if (chunksize >= *size - newsize) { - /* - * XXX: The message is a bit confusing. Isn't the real problem that - * the specified chunk size is greater than the number of bytes - * left in the buffer? This probably means the connection got - * closed prematurely. To be investigated after 3.0.17 is out. - */ log_error(LOG_LEVEL_ERROR, - "Chunk size %d exceeds buffer size %d in \"chunked\" transfer coding", - chunksize, *size); + "Chunk size %u exceeds buffered data left. " + "Already digested %u of %u buffered bytes.", + chunksize, (unsigned int)newsize, (unsigned int)*size); return JB_ERR_PARSE; } + newsize += chunksize; from_p += 2; memmove(to_p, from_p, (size_t) chunksize);