X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=blobdiff_plain;f=filters.c;h=4b4f33e95d4c733be1cc2292bb800a8a0b761fc8;hp=54bd06dcd96a2464ec25c35a622bf01087755a69;hb=21a2acc10c95913f50d72aa70815254a9a7702ef;hpb=43980e5c0dbe1b2090fa04f69c3989960f1d8975 diff --git a/filters.c b/filters.c index 54bd06dc..4b4f33e9 100644 --- a/filters.c +++ b/filters.c @@ -1,4 +1,4 @@ -const char filters_rcs[] = "$Id: filters.c,v 1.181 2014/06/02 06:19:05 fabiankeil Exp $"; +const char filters_rcs[] = "$Id: filters.c,v 1.195 2015/12/27 12:46:34 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/filters.c,v $ @@ -347,12 +347,7 @@ int acl_addr(const char *aspec, struct access_control_addr *aca) * Use a temporary acl spec copy so we can log * the unmodified original in case of parse errors. */ - acl_spec = strdup(aspec); - if (acl_spec == NULL) - { - /* XXX: This will be logged as parse error. */ - return(-1); - } + acl_spec = strdup_or_die(aspec); if ((p = strchr(acl_spec, '/')) != NULL) { @@ -391,13 +386,19 @@ int acl_addr(const char *aspec, struct access_control_addr *aca) { p = strchr(acl_spec, ':'); } + if (p != NULL) + { + assert(*p == ':'); + *p = '\0'; + p++; + } #ifdef HAVE_RFC2553 memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; - i = getaddrinfo(acl_spec, ((p) ? ++p : NULL), &hints, &result); + i = getaddrinfo(acl_spec, p, &hints, &result); if (i != 0) { @@ -416,7 +417,6 @@ int acl_addr(const char *aspec, struct access_control_addr *aca) { char *endptr; - *p++ = '\0'; port = strtol(p, &endptr, 10); if (port <= 0 || port > 65535 || *endptr != '\0') @@ -582,12 +582,7 @@ struct http_response *block_url(struct client_state *csp) /* and handle accordingly: */ if ((p == NULL) || (0 == strcmpic(p, "pattern"))) { - rsp->status = strdup("403 Request blocked by Privoxy"); - if (rsp->status == NULL) - { - free_http_response(rsp); - return cgi_error_memory(); - } + rsp->status = strdup_or_die("403 Request blocked by Privoxy"); rsp->body = bindup(image_pattern_data, image_pattern_length); if (rsp->body == NULL) { @@ -604,12 +599,7 @@ struct http_response *block_url(struct client_state *csp) } else if (0 == strcmpic(p, "blank")) { - rsp->status = strdup("403 Request blocked by Privoxy"); - if (rsp->status == NULL) - { - free_http_response(rsp); - return cgi_error_memory(); - } + rsp->status = strdup_or_die("403 Request blocked by Privoxy"); rsp->body = bindup(image_blank_data, image_blank_length); if (rsp->body == NULL) { @@ -626,12 +616,7 @@ struct http_response *block_url(struct client_state *csp) } else { - rsp->status = strdup("302 Local Redirect from Privoxy"); - if (rsp->status == NULL) - { - free_http_response(rsp); - return cgi_error_memory(); - } + rsp->status = strdup_or_die("302 Local Redirect from Privoxy"); if (enlist_unique_header(rsp->headers, "Location", p)) { @@ -651,7 +636,7 @@ struct http_response *block_url(struct client_state *csp) new_content_type = csp->action->string[ACTION_STRING_CONTENT_TYPE]; freez(rsp->body); - rsp->body = strdup(" "); + rsp->body = strdup_or_die(" "); rsp->content_length = 1; if (csp->config->feature_flags & RUNTIME_FEATURE_EMPTY_DOC_RETURNS_OK) @@ -662,18 +647,13 @@ struct http_response *block_url(struct client_state *csp) * Return a 200 OK status for pages blocked with +handle-as-empty-document * if the "handle-as-empty-doc-returns-ok" runtime config option is set. */ - rsp->status = strdup("200 Request blocked by Privoxy"); + rsp->status = strdup_or_die("200 Request blocked by Privoxy"); } else { - rsp->status = strdup("403 Request blocked by Privoxy"); + rsp->status = strdup_or_die("403 Request blocked by Privoxy"); } - if (rsp->status == NULL) - { - free_http_response(rsp); - return cgi_error_memory(); - } if (new_content_type != 0) { log_error(LOG_LEVEL_HEADER, "Overwriting Content-Type with %s", new_content_type); @@ -693,12 +673,7 @@ struct http_response *block_url(struct client_state *csp) jb_err err; struct map * exports; - rsp->status = strdup("403 Request blocked by Privoxy"); - if (rsp->status == NULL) - { - free_http_response(rsp); - return cgi_error_memory(); - } + rsp->status = strdup_or_die("403 Request blocked by Privoxy"); exports = default_exports(csp, NULL); if (exports == NULL) @@ -802,9 +777,9 @@ struct http_response *trust_url(struct client_state *csp) return cgi_error_memory(); } - rsp->status = strdup("403 Request blocked by Privoxy"); + rsp->status = strdup_or_die("403 Request blocked by Privoxy"); exports = default_exports(csp, NULL); - if (exports == NULL || rsp->status == NULL) + if (exports == NULL) { free_http_response(rsp); return cgi_error_memory(); @@ -836,7 +811,7 @@ struct http_response *trust_url(struct client_state *csp) /* * Export the trust list */ - p = strdup(""); + p = strdup_or_die(""); for (tl = csp->config->trust_list; (t = *tl) != NULL ; tl++) { snprintf(buf, sizeof(buf), "
  • %s
  • \n", t->spec); @@ -858,7 +833,7 @@ struct http_response *trust_url(struct client_state *csp) { struct list_entry *l; - p = strdup(""); + p = strdup_or_die(""); for (l = csp->config->trust_info->first; l ; l = l->next) { snprintf(buf, sizeof(buf), "
  • %s
    \n", l->str, l->str); @@ -1131,14 +1106,8 @@ char *get_last_url(char *subject, const char *redirect_mode) } if (NULL != url_segment) { - url_segment = strdup(url_segment); + url_segment = strdup_or_die(url_segment); freez(dtoken); - if (url_segment == NULL) - { - log_error(LOG_LEVEL_ERROR, - "Out of memory while searching for redirects."); - return NULL; - } break; } freez(dtoken); @@ -1238,11 +1207,14 @@ struct http_response *redirect_url(struct client_state *csp) * properly formatted URL and use it for the redirection * directly. * - * According to RFC 2616 section 14.30 the URL - * has to be absolute and if the user tries: - * +redirect{shit/this/will/be/parsed/as/pcrs_command.html} + * According to (the now obsolete) RFC 2616 section 14.30 + * the URL has to be absolute and if the user tries: + * +redirect{sadly/this/will/be/parsed/as/pcrs_command.html} * she would get undefined results anyway. * + * RFC 7231 7.1.2 actually allows relative references, + * but those start with a leading slash (RFC 3986 4.2) and + * thus can't be mistaken for pcrs commands either. */ if (*redirection_string == 's') @@ -1321,8 +1293,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")))) + rsp->status = strdup_or_die("302 Local Redirect from Privoxy"); + if (enlist_unique_header(rsp->headers, "Location", new_url)) { freez(new_url); free_http_response(rsp); @@ -1467,7 +1439,7 @@ int is_untrusted_url(const struct client_state *csp) { char * path; char * path_end; - char * new_entry = strdup("~"); + char * new_entry = strdup_or_die("~"); string_append(&new_entry, csp->http->hostport); @@ -1873,6 +1845,7 @@ static char *execute_external_filter(const struct client_state *csp, { log_error(LOG_LEVEL_ERROR, "fwrite(..., %d, 1, ..) failed: %E", *size); unlink(file_name); + fclose(fp); return NULL; } fclose(fp); @@ -1903,7 +1876,8 @@ static char *execute_external_filter(const struct client_state *csp, return NULL; } - filter_output = malloc_or_die(*size); + /* Allocate at least one byte */ + filter_output = malloc_or_die(*size + 1); new_size = 0; while (!feof(fp) && !ferror(fp)) @@ -1917,7 +1891,7 @@ static char *execute_external_filter(const struct client_state *csp, char *p; /* Could be considered wasteful if the content is 'large'. */ - *size = (*size != 0) ? *size * 2 : READ_LENGTH; + *size += (*size >= READ_LENGTH) ? *size : READ_LENGTH; p = realloc(filter_output, *size); if (p == NULL) @@ -1928,6 +1902,7 @@ static char *execute_external_filter(const struct client_state *csp, } filter_output = p; } + assert(new_size + READ_LENGTH < *size); len = fread(&filter_output[new_size], 1, READ_LENGTH, fp); if (len > 0) { @@ -2041,12 +2016,11 @@ static filter_function_ptr get_filter_function(const struct client_state *csp) * the content type and action settings. */ if ((csp->content_type & CT_TEXT) && - (csp->rlist != NULL) && (!list_is_empty(csp->action->multi[ACTION_MULTI_FILTER]))) { filter_function = pcrs_filter_response; } - else if ((csp->content_type & CT_GIF) && + else if ((csp->content_type & CT_GIF) && (csp->action->flags & ACTION_DEANIMATE)) { filter_function = gif_deanimate_response; @@ -2061,7 +2035,8 @@ static filter_function_ptr get_filter_function(const struct client_state *csp) * Function : remove_chunked_transfer_coding * * Description : In-situ remove the "chunked" transfer coding as defined - * in rfc2616 from a buffer. + * in RFC 7230 4.1 from a buffer. XXX: The implementation + * is neither complete nor compliant (TODO #129). * * Parameters : * 1 : buffer = Pointer to the text buffer @@ -2252,7 +2227,8 @@ char *execute_content_filters(struct client_state *csp) content = (content_filter != NULL) ? (*content_filter)(csp) : NULL; #ifdef FEATURE_EXTERNAL_FILTERS - if (!list_is_empty(csp->action->multi[ACTION_MULTI_EXTERNAL_FILTER])) + if ((csp->content_type & CT_TEXT) && + !list_is_empty(csp->action->multi[ACTION_MULTI_EXTERNAL_FILTER])) { struct list_entry *filtername; size_t size = (size_t)csp->content_length; @@ -2266,7 +2242,15 @@ char *execute_content_filters(struct client_state *csp) for (filtername = csp->action->multi[ACTION_MULTI_EXTERNAL_FILTER]->first; filtername ; filtername = filtername->next) { - content = execute_external_filter(csp, filtername->str, content, &size); + char *result = execute_external_filter(csp, filtername->str, content, &size); + if (result != NULL) + { + if (content != csp->iob->cur) + { + free(content); + } + content = result; + } } csp->flags |= CSP_FLAG_MODIFIED; csp->content_length = size; @@ -2373,7 +2357,7 @@ void apply_url_actions(struct current_action_spec *action, * Invalid syntax is fatal. * *********************************************************************/ -const static struct forward_spec *get_forward_override_settings(struct client_state *csp) +static const struct forward_spec *get_forward_override_settings(struct client_state *csp) { const char *forward_override_line = csp->action->string[ACTION_STRING_FORWARD_OVERRIDE]; char forward_settings[BUFFER_SIZE]; @@ -2576,12 +2560,7 @@ struct http_response *direct_response(struct client_state *csp) return cgi_error_memory(); } - if (NULL == (rsp->status = strdup("501 Not Implemented"))) - { - free_http_response(rsp); - return cgi_error_memory(); - } - + rsp->status = strdup_or_die("501 Not Implemented"); rsp->is_static = 1; rsp->crunch_reason = UNSUPPORTED; @@ -2653,8 +2632,8 @@ int content_requires_filtering(struct client_state *csp) * the content type and action settings. */ if ((csp->content_type & CT_TEXT) && - (csp->rlist != NULL) && - (!list_is_empty(csp->action->multi[ACTION_MULTI_FILTER]))) + (!list_is_empty(csp->action->multi[ACTION_MULTI_FILTER]) || + !list_is_empty(csp->action->multi[ACTION_MULTI_EXTERNAL_FILTER]))) { return TRUE; } @@ -2664,7 +2643,7 @@ int content_requires_filtering(struct client_state *csp) return TRUE; } - return (!list_is_empty(csp->action->multi[ACTION_MULTI_EXTERNAL_FILTER])); + return FALSE; }