X-Git-Url: http://www.privoxy.org/gitweb/?a=blobdiff_plain;f=filters.c;h=fcca26697139e35dac49fa7eceb45dc68124c4aa;hb=60c86e3736979de77fe4bb564366fbbbc22270f1;hp=467b8029de225f9100d46449dd55b178d7547a35;hpb=9b87e59614c7e19ed0b40d9037fbf77ae9871214;p=privoxy.git diff --git a/filters.c b/filters.c index 467b8029..fcca2669 100644 --- a/filters.c +++ b/filters.c @@ -1,4 +1,4 @@ -const char filters_rcs[] = "$Id: filters.c,v 1.177 2013/04/23 09:37:28 fabiankeil Exp $"; +const char filters_rcs[] = "$Id: filters.c,v 1.179 2013/12/24 13:32:51 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/filters.c,v $ @@ -1525,6 +1525,66 @@ int is_untrusted_url(const struct client_state *csp) #endif /* def FEATURE_TRUST */ +/********************************************************************* + * + * Function : get_filter + * + * Description : Get a filter with a given name and type. + * Note that taggers are filters, too. + * + * Parameters : + * 1 : csp = Current client state (buffers, headers, etc...) + * 2 : requested_name = Name of the content filter to get + * 3 : requested_type = Type of the filter to tagger to lookup + * + * Returns : A pointer to the requested filter + * or NULL if the filter wasn't found + * + *********************************************************************/ +struct re_filterfile_spec *get_filter(const struct client_state *csp, + const char *requested_name, + enum filter_type requested_type) +{ + int i; + struct re_filterfile_spec *b; + struct file_list *fl; + + for (i = 0; i < MAX_AF_FILES; i++) + { + fl = csp->rlist[i]; + if ((NULL == fl) || (NULL == fl->f)) + { + /* + * Either there are no filter files left or this + * filter file just contains no valid filters. + * + * Continue to be sure we don't miss valid filter + * files that are chained after empty or invalid ones. + */ + continue; + } + + for (b = fl->f; b != NULL; b = b->next) + { + if (b->type != requested_type) + { + /* The callers isn't interested in this filter type. */ + continue; + } + if (strcmp(b->name, requested_name) == 0) + { + /* The requested filter has been found. Abort search. */ + return b; + } + } + } + + /* No filter with the given name and type exists. */ + return NULL; + +} + + /********************************************************************* * * Function : pcrs_filter_response @@ -1543,14 +1603,12 @@ int is_untrusted_url(const struct client_state *csp) static char *pcrs_filter_response(struct client_state *csp) { int hits = 0; - int i; size_t size, prev_size; char *old = NULL; char *new = NULL; pcrs_job *job; - struct file_list *fl; struct re_filterfile_spec *b; struct list_entry *filtername; @@ -1572,108 +1630,87 @@ static char *pcrs_filter_response(struct client_state *csp) size = (size_t)(csp->iob->eod - csp->iob->cur); old = csp->iob->cur; - for (i = 0; i < MAX_AF_FILES; i++) - { - fl = csp->rlist[i]; - if ((NULL == fl) || (NULL == fl->f)) - { - /* - * Either there are no filter files - * left, or this filter file just - * contains no valid filters. - * - * Continue to be sure we don't miss - * valid filter files that are chained - * after empty or invalid ones. - */ - continue; - } /* * For all applying +filter actions, look if a filter by that * name exists and if yes, execute it's pcrs_joblist on the * buffer. */ - for (b = fl->f; b; b = b->next) + for (filtername = csp->action->multi[ACTION_MULTI_FILTER]->first; + filtername != NULL; filtername = filtername->next) { - if (b->type != FT_CONTENT_FILTER) + int current_hits = 0; /* Number of hits caused by this filter */ + int job_number = 0; /* Which job we're currently executing */ + int job_hits = 0; /* How many hits the current job caused */ + pcrs_job *joblist; + + b = get_filter(csp, filtername->str, FT_CONTENT_FILTER); + if (b == NULL) { - /* Skip header filters */ continue; } - for (filtername = csp->action->multi[ACTION_MULTI_FILTER]->first; - filtername ; filtername = filtername->next) - { - if (strcmp(b->name, filtername->str) == 0) - { - int current_hits = 0; /* Number of hits caused by this filter */ - int job_number = 0; /* Which job we're currently executing */ - int job_hits = 0; /* How many hits the current job caused */ - pcrs_job *joblist = b->joblist; + joblist = b->joblist; - if (b->dynamic) joblist = compile_dynamic_pcrs_job_list(csp, b); + if (b->dynamic) joblist = compile_dynamic_pcrs_job_list(csp, b); - if (NULL == joblist) - { - log_error(LOG_LEVEL_RE_FILTER, "Filter %s has empty joblist. Nothing to do.", b->name); - continue; - } + if (NULL == joblist) + { + log_error(LOG_LEVEL_RE_FILTER, "Filter %s has empty joblist. Nothing to do.", b->name); + continue; + } - prev_size = size; - /* Apply all jobs from the joblist */ - for (job = joblist; NULL != job; job = job->next) - { - job_number++; - job_hits = pcrs_execute(job, old, size, &new, &size); + prev_size = size; + /* Apply all jobs from the joblist */ + for (job = joblist; NULL != job; job = job->next) + { + job_number++; + job_hits = pcrs_execute(job, old, size, &new, &size); - if (job_hits >= 0) - { - /* - * That went well. Continue filtering - * and use the result of this job as - * input for the next one. - */ - current_hits += job_hits; - if (old != csp->iob->cur) - { - freez(old); - } - old = new; - } - else - { - /* - * This job caused an unexpected error. Inform the user - * and skip the rest of the jobs in this filter. We could - * continue with the next job, but usually the jobs - * depend on each other or are similar enough to - * fail for the same reason. - * - * At the moment our pcrs expects the error codes of pcre 3.4, - * but newer pcre versions can return additional error codes. - * As a result pcrs_strerror()'s error message might be - * "Unknown error ...", therefore we print the numerical value - * as well. - * - * XXX: Is this important enough for LOG_LEVEL_ERROR or - * should we use LOG_LEVEL_RE_FILTER instead? - */ - log_error(LOG_LEVEL_ERROR, "Skipped filter \'%s\' after job number %u: %s (%d)", - b->name, job_number, pcrs_strerror(job_hits), job_hits); - break; - } + if (job_hits >= 0) + { + /* + * That went well. Continue filtering + * and use the result of this job as + * input for the next one. + */ + current_hits += job_hits; + if (old != csp->iob->cur) + { + freez(old); } + old = new; + } + else + { + /* + * This job caused an unexpected error. Inform the user + * and skip the rest of the jobs in this filter. We could + * continue with the next job, but usually the jobs + * depend on each other or are similar enough to + * fail for the same reason. + * + * At the moment our pcrs expects the error codes of pcre 3.4, + * but newer pcre versions can return additional error codes. + * As a result pcrs_strerror()'s error message might be + * "Unknown error ...", therefore we print the numerical value + * as well. + * + * XXX: Is this important enough for LOG_LEVEL_ERROR or + * should we use LOG_LEVEL_RE_FILTER instead? + */ + log_error(LOG_LEVEL_ERROR, "Skipped filter \'%s\' after job number %u: %s (%d)", + b->name, job_number, pcrs_strerror(job_hits), job_hits); + break; + } + } - if (b->dynamic) pcrs_free_joblist(joblist); + if (b->dynamic) pcrs_free_joblist(joblist); - log_error(LOG_LEVEL_RE_FILTER, - "filtering %s%s (size %d) with \'%s\' produced %d hits (new size %d).", - csp->http->hostport, csp->http->path, prev_size, b->name, current_hits, size); + log_error(LOG_LEVEL_RE_FILTER, + "filtering %s%s (size %d) with \'%s\' produced %d hits (new size %d).", + csp->http->hostport, csp->http->path, prev_size, b->name, current_hits, size); - hits += current_hits; - } - } - } + hits += current_hits; } /*