X-Git-Url: http://www.privoxy.org/gitweb/?a=blobdiff_plain;f=filters.c;h=e2f490c7d274499026920b0f09878154921f4d78;hb=8c3e4f19001300c07cb076353eba625e4729fdd2;hp=1949b21c3c3c291b6f31f8baaacdea1c55638e6d;hpb=0428133610c525457cb16f7ac6a54203a2743d6c;p=privoxy.git diff --git a/filters.c b/filters.c index 1949b21c..e2f490c7 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.154 2011/10/30 16:22:46 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 @@ -1269,8 +1325,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);