X-Git-Url: http://www.privoxy.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=filters.c;h=39946389b518e5b512a60eba158a8c44fd5fabce;hb=38a3bb7f642b091a8830b75fe0c8b514209b6175;hp=1949b21c3c3c291b6f31f8baaacdea1c55638e6d;hpb=0428133610c525457cb16f7ac6a54203a2743d6c;p=privoxy.git diff --git a/filters.c b/filters.c index 1949b21c..39946389 100644 --- a/filters.c +++ b/filters.c @@ -1,4 +1,4 @@ -const char filters_rcs[] = "$Id: filters.c,v 1.144 2011/07/30 15:15:25 fabiankeil Exp $"; +const char filters_rcs[] = "$Id: filters.c,v 1.155 2011/11/06 11:36:42 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/filters.c,v $ @@ -78,6 +78,11 @@ const char filters_rcs[] = "$Id: filters.c,v 1.144 2011/07/30 15:15:25 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 @@ -1106,8 +1111,55 @@ char *get_last_url(char *subject, const char *redirect_mode) } if (0 == strcmpic(redirect_mode, "check-decoded-url")) - { - log_error(LOG_LEVEL_REDIRECTS, "Decoding \"%s\" if necessary.", 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, + * and look for a URL in the decoded result. + * Keep the last one we spot. + */ + char *found = NULL; + + privoxy_mutex_lock(&strtok_mutex); + char *token = strtok(subject, "?&"); + while (token) + { + char *dtoken = url_decode(token); + if (NULL == dtoken) + { + log_error(LOG_LEVEL_ERROR, "Unable to decode \"%s\".", token); + 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) + { + freez(found); + found = strdup(last_url); + if (found == NULL) + { + log_error(LOG_LEVEL_ERROR, + "Out of memory while searching for redirects."); + privoxy_mutex_unlock(&strtok_mutex); + return NULL; + } + } + freez(dtoken); + token = strtok(NULL, "?&"); + } + privoxy_mutex_unlock(&strtok_mutex); + freez(subject); + + return found; +#else new_url = url_decode(subject); if (new_url != NULL) { @@ -1118,9 +1170,13 @@ char *get_last_url(char *subject, const char *redirect_mode) { log_error(LOG_LEVEL_ERROR, "Unable to decode \"%s\".", subject); } +#endif /* defined(MUTEX_LOCKS_AVAILABLE) && defined(HAVE_STRTOK) */ } - log_error(LOG_LEVEL_REDIRECTS, "Checking \"%s\" for 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 @@ -1252,6 +1308,20 @@ struct http_response *redirect_url(struct client_state *csp) /* Did any redirect action trigger? */ if (new_url) { + if (url_requires_percent_encoding(new_url)) + { + char *encoded_url; + log_error(LOG_LEVEL_REDIRECTS, "Percent-encoding redirect URL: %N", + strlen(new_url), new_url); + encoded_url = percent_encode_url(new_url); + freez(new_url); + if (encoded_url == NULL) + { + return cgi_error_memory(); + } + new_url = encoded_url; + } + if (0 == strcmpic(new_url, csp->http->url)) { log_error(LOG_LEVEL_ERROR, @@ -1269,8 +1339,8 @@ struct http_response *redirect_url(struct client_state *csp) return cgi_error_memory(); } - if ( enlist_unique_header(rsp->headers, "Location", new_url) - || (NULL == (rsp->status = strdup("302 Local Redirect from Privoxy"))) ) + if (enlist_unique_header(rsp->headers, "Location", new_url) + || (NULL == (rsp->status = strdup("302 Local Redirect from Privoxy")))) { freez(new_url); free_http_response(rsp);