X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=blobdiff_plain;f=filters.c;h=e30a24c835110339f47831548b07972b853cf279;hp=9a079667562d8264a4973059dc3a2a97defd90c3;hb=ef90a49bca7cc597192e8e3d77de6de9cdf88f57;hpb=da23dc8543fc54465eb3d247c7b67188cce2abcd diff --git a/filters.c b/filters.c index 9a079667..e30a24c8 100644 --- a/filters.c +++ b/filters.c @@ -1,4 +1,4 @@ -const char filters_rcs[] = "$Id: filters.c,v 1.27 2001/08/05 16:06:20 jongfoster Exp $"; +const char filters_rcs[] = "$Id: filters.c,v 1.35 2001/10/07 15:41:23 oes Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/filters.c,v $ @@ -38,6 +38,48 @@ const char filters_rcs[] = "$Id: filters.c,v 1.27 2001/08/05 16:06:20 jongfoster * * Revisions : * $Log: filters.c,v $ + * Revision 1.35 2001/10/07 15:41:23 oes + * Replaced 6 boolean members of csp with one bitmap (csp->flags) + * + * New function remove_chunked_transfer_coding that strips chunked + * transfer coding to plain and is called by pcrs_filter_response + * and gif_deanimate_response if neccessary + * + * Improved handling of zero-change re_filter runs + * + * pcrs_filter_response and gif_deanimate_response now remove + * chunked transfer codeing before processing the body. + * + * Revision 1.34 2001/09/20 15:49:36 steudten + * + * Fix BUG: Change int size to size_t size in pcrs_filter_response(). + * See cgi.c fill_template(). + * + * Revision 1.33 2001/09/16 17:05:14 jongfoster + * Removing unused #include showarg.h + * + * Revision 1.32 2001/09/16 13:21:27 jongfoster + * Changes to use new list functions. + * + * Revision 1.31 2001/09/16 11:38:02 jongfoster + * Splitting fill_template() into 2 functions: + * template_load() loads the file + * template_fill() performs the PCRS regexps. + * This is because the CGI edit interface has a "table row" + * template which is used many times in the page - this + * change means it's only loaded from disk once. + * + * Revision 1.30 2001/09/16 11:00:10 jongfoster + * New function alloc_http_response, for symmetry with free_http_response + * + * Revision 1.29 2001/09/13 23:32:40 jongfoster + * Moving image data to cgi.c rather than cgi.h + * Fixing a GPF under Win32 (and any other OS that protects global + * constants from being written to). + * + * Revision 1.28 2001/09/10 10:18:51 oes + * Silenced compiler warnings + * * Revision 1.27 2001/08/05 16:06:20 jongfoster * Modifiying "struct map" so that there are now separate header and * "map_entry" structures. This means that functions which modify a @@ -261,6 +303,7 @@ const char filters_rcs[] = "$Id: filters.c,v 1.27 2001/08/05 16:06:20 jongfoster #include #include #include +#include #ifndef _WIN32 #include @@ -272,12 +315,8 @@ const char filters_rcs[] = "$Id: filters.c,v 1.27 2001/08/05 16:06:20 jongfoster #include "project.h" #include "filters.h" #include "encode.h" -#include "jcc.h" -#include "showargs.h" #include "parsers.h" #include "ssplit.h" -#include "gateway.h" -#include "jbsockets.h" #include "errlog.h" #include "jbsockets.h" #include "miscutil.h" @@ -439,6 +478,86 @@ int acl_addr(char *aspec, struct access_control_addr *aca) #endif /* def FEATURE_ACL */ +/********************************************************************* + * + * Function : match_portlist + * + * Description : Check if a given number is covered by a comma + * separated list of numbers and ranges (a,b-c,d,..) + * + * Parameters : + * 1 : portlist = String with list + * 2 : port = port to check + * + * Returns : 0 => no match + * 1 => match + * + *********************************************************************/ +int match_portlist(const char *portlist, int port) +{ + char *min, *max, *next, *portlist_copy; + + min = next = portlist_copy = strdup(portlist); + + /* + * Zero-terminate first item and remember offset for next + */ + if (NULL != (next = strchr(portlist_copy, (int) ','))) + { + *next++ = '\0'; + } + + /* + * Loop through all items, checking for match + */ + while(min) + { + if (NULL == (max = strchr(min, (int) '-'))) + { + /* + * No dash, check for equality + */ + if (port == atoi(min)) + { + free(portlist_copy); + return(1); + } + } + else + { + /* + * This is a range, so check if between min and max, + * or, if max was omitted, between min and 65K + */ + *max++ = '\0'; + if(port >= atoi(min) && port <= (atoi(max) ? atoi(max) : 65535)) + { + free(portlist_copy); + return(1); + } + + } + + /* + * Jump to next item + */ + min = next; + + /* + * Zero-terminate next item and remember offset for n+1 + */ + if ((NULL != next) && (NULL != (next = strchr(next, (int) ',')))) + { + *next++ = '\0'; + } + } + + free(portlist_copy); + return 0; + +} + + /********************************************************************* * * Function : block_url @@ -469,7 +588,7 @@ struct http_response *block_url(struct client_state *csp) /* * Else, prepare a response */ - if (NULL == ( rsp = (struct http_response *)zalloc(sizeof(*rsp)))) + if (NULL == (rsp = alloc_http_response())) { return NULL; } @@ -488,15 +607,15 @@ struct http_response *block_url(struct client_state *csp) /* and handle accordingly: */ if ((p == NULL) || (0 == strcmpic(p, "logo"))) { - rsp->body = bindup(JBGIF, sizeof(JBGIF)); - rsp->content_length = sizeof(JBGIF); + rsp->body = bindup(image_junkbuster_gif_data, image_junkbuster_gif_length); + rsp->content_length = image_junkbuster_gif_length; enlist_unique_header(rsp->headers, "Content-Type", "image/gif"); } else if (0 == strcmpic(p, "blank")) { - rsp->body = bindup(BLANKGIF, sizeof(BLANKGIF)); - rsp->content_length = sizeof(BLANKGIF); + rsp->body = bindup(image_blank_gif_data, image_blank_gif_length); + rsp->content_length = image_blank_gif_length; enlist_unique_header(rsp->headers, "Content-Type", "image/gif"); } @@ -525,7 +644,8 @@ struct http_response *block_url(struct client_state *csp) map(exports, "path", 1, csp->http->path, 1); map(exports, "path-html", 1, html_encode(csp->http->path), 0); - rsp->body = fill_template(csp, "blocked", exports); + rsp->body = template_load(csp, "blocked"); + template_fill(&rsp->body, exports); free_map(exports); /* @@ -585,7 +705,7 @@ struct http_response *trust_url(struct client_state *csp) /* * Else, prepare a response: */ - if (NULL == ( rsp = (struct http_response *)zalloc(sizeof(*rsp)))) + if (NULL == (rsp = alloc_http_response())) { return NULL; } @@ -625,11 +745,11 @@ struct http_response *trust_url(struct client_state *csp) /* * Export the trust info, if available */ - if (csp->config->trust_info->next) + if (csp->config->trust_info->first) { - struct list *l; + struct list_entry *l; - for (l = csp->config->trust_info->next; l ; l = l->next) + for (l = csp->config->trust_info->first; l ; l = l->next) { sprintf(buf, "
  • %s
    \n",l->str, l->str); p = strsav(p, buf); @@ -653,7 +773,8 @@ struct http_response *trust_url(struct client_state *csp) /* * Build the response */ - rsp->body = fill_template(csp, "untrusted", exports); + rsp->body = template_load(csp, "untrusted"); + template_fill(&rsp->body, exports); free_map(exports); return(finish_http_response(rsp)); @@ -699,7 +820,7 @@ struct http_response *redirect_url(struct client_state *csp) { log_error(LOG_LEVEL_REDIRECTS, "redirecting to: %s", q); - if (NULL == ( rsp = zalloc(sizeof(*rsp)))) + if (NULL == (rsp = alloc_http_response())) { return NULL; } @@ -930,7 +1051,7 @@ int is_untrusted_url(struct client_state *csp) * Description : Apply all the pcrs jobs from the joblist (re_filterfile) * to the text buffer that's been accumulated in * csp->iob->buf and set csp->content_length to the modified - * size. + * size and raise the CSP_FLAG_MODIFIED flag if appropriate. * * Parameters : * 1 : csp = Current client state (buffers, headers, etc...) @@ -942,7 +1063,7 @@ int is_untrusted_url(struct client_state *csp) char *pcrs_filter_response(struct client_state *csp) { int hits=0; - int size = csp->iob->eod - csp->iob->cur; + size_t size; char *old = csp->iob->cur, *new = NULL; pcrs_job *job; @@ -950,11 +1071,27 @@ char *pcrs_filter_response(struct client_state *csp) struct file_list *fl; struct re_filterfile_spec *b; - /* Sanity first ;-) */ - if (size <= 0) + /* Sanity first */ + if (csp->iob->cur >= csp->iob->eod) { return(NULL); } + size = csp->iob->eod - csp->iob->cur; + + /* + * If the body has a "chunked" transfer-encoding, + * get rid of it first, adjusting size and iob->eod + */ + if (csp->flags & CSP_FLAG_CHUNKED) + { + log_error(LOG_LEVEL_RE_FILTER, "Need to de-chunk first"); + if (0 == (size = remove_chunked_transfer_coding(csp->iob->cur, size))) + { + return(NULL); + } + csp->iob->eod = csp->iob->cur + size; + csp->flags |= CSP_FLAG_MODIFIED; + } if ( ( NULL == (fl = csp->rlist) ) || ( NULL == (b = fl->f) ) ) { @@ -981,10 +1118,20 @@ char *pcrs_filter_response(struct client_state *csp) log_error(LOG_LEVEL_RE_FILTER, " produced %d hits (new size %d).", hits, size); - csp->content_length = size; + /* + * If there were no hits, destroy our copy and let + * chat() use the original in csp->iob + */ + if (!hits) + { + free(new); + return(NULL); + } - /* fwiw, reset the iob */ + csp->flags |= CSP_FLAG_MODIFIED; + csp->content_length = size; IOB_RESET(csp); + return(new); } @@ -995,8 +1142,8 @@ char *pcrs_filter_response(struct client_state *csp) * Function : gif_deanimate_response * * Description : Deanimate the GIF image that has been accumulated in - * csp->iob->buf and set csp->content_length to the modified - * size. + * csp->iob->buf, set csp->content_length to the modified + * size and raise the CSP_FLAG_MODIFIED flag. * * Parameters : * 1 : csp = Current client state (buffers, headers, etc...) @@ -1011,6 +1158,21 @@ char *gif_deanimate_response(struct client_state *csp) char *p; int size = csp->iob->eod - csp->iob->cur; + /* + * If the body has a "chunked" transfer-encoding, + * get rid of it first, adjusting size and iob->eod + */ + if (csp->flags & CSP_FLAG_CHUNKED) + { + log_error(LOG_LEVEL_DEANIMATE, "Need to de-chunk first"); + if (0 == (size = remove_chunked_transfer_coding(csp->iob->cur, size))) + { + return(NULL); + } + csp->iob->eod = csp->iob->cur + size; + csp->flags |= CSP_FLAG_MODIFIED; + } + if ( (NULL == (in = (struct binbuffer *)zalloc(sizeof *in ))) || (NULL == (out = (struct binbuffer *)zalloc(sizeof *out))) ) { @@ -1032,6 +1194,7 @@ char *gif_deanimate_response(struct client_state *csp) { log_error(LOG_LEVEL_DEANIMATE, "Success! GIF shrunk from %d bytes to %d.", size, out->offset); csp->content_length = out->offset; + csp->flags |= CSP_FLAG_MODIFIED; p = out->buffer; free(in); free(out); @@ -1041,6 +1204,65 @@ char *gif_deanimate_response(struct client_state *csp) } +/********************************************************************* + * + * Function : remove_chunked_transfer_coding + * + * Description : In-situ remove the "chunked" transfer coding as defined + * in rfc2616 from a buffer. + * + * Parameters : + * 1 : buffer = Pointer to the text buffer + * 2 : size = Number of bytes to be processed + * + * Returns : The new size, i.e. the number of bytes from buffer which + * are occupied by the stripped body, or 0 in case something + * went wrong + * + *********************************************************************/ +int remove_chunked_transfer_coding(char *buffer, const size_t size) +{ + size_t newsize = 0; + unsigned int chunksize = 0; + char *from_p, *to_p; + + assert(buffer); + from_p = to_p = buffer; + + if (sscanf(buffer, "%x", &chunksize) != 1) + { + log_error(LOG_LEVEL_ERROR, "Invalid first chunksize while stripping \"chunked\" transfer coding"); + return(0); + } + + while (chunksize > 0) + { + if (NULL == (from_p = strstr(from_p, "\r\n"))) + { + log_error(LOG_LEVEL_ERROR, "Parse error while stripping \"chunked\" transfer coding"); + return(0); + } + newsize += chunksize; + from_p += 2; + + memmove(to_p, from_p, (size_t) chunksize); + to_p = buffer + newsize; + from_p += chunksize + 2; + + if (sscanf(from_p, "%x", &chunksize) != 1) + { + log_error(LOG_LEVEL_ERROR, "Parse error while stripping \"chunked\" transfer coding"); + return(0); + } + } + + /* FIXME: Should this get its own loglevel? */ + log_error(LOG_LEVEL_RE_FILTER, "De-chunking successful. Shrunk from %d to %d\n", size, newsize); + return(newsize); + +} + + /********************************************************************* * * Function : url_actions @@ -1147,12 +1369,10 @@ void apply_url_actions(struct current_action_spec *action, const struct forward_spec * forward_url(struct http_request *http, struct client_state *csp) { - static const struct forward_spec fwd_default[1]; + static const struct forward_spec fwd_default[1] = { FORWARD_SPEC_INITIALIZER }; struct forward_spec *fwd = csp->config->forward; struct url_spec url[1]; - memset(&fwd_default, '\0', sizeof(struct forward_spec)); - if (fwd == NULL) { return(fwd_default);