X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=blobdiff_plain;f=parsers.c;h=14aa99ea8cbbb3a603e8501a706fd281fab97fed;hp=d2ef046a0205c1cfb912a5b566ad8bea3dc725f8;hb=41bcde325feaf65a42fe2c4ab21cee5771ac60ad;hpb=d718332b42f884d9c3c2fd0cfa9b83f4973c6971 diff --git a/parsers.c b/parsers.c index d2ef046a..14aa99ea 100644 --- a/parsers.c +++ b/parsers.c @@ -4,7 +4,7 @@ * * Purpose : Declares functions to parse/crunch headers and pages. * - * Copyright : Written by and Copyright (C) 2001-2020 the + * Copyright : Written by and Copyright (C) 2001-2021 the * Privoxy team. https://www.privoxy.org/ * * Based on the Internet Junkbuster originally written @@ -291,6 +291,27 @@ long flush_iob(jb_socket fd, struct iob *iob, unsigned int delay) } +/********************************************************************* + * + * Function : can_add_to_iob + * + * Description : Checks if the given number of bytes can be added to the given iob + * without exceeding the given buffer limit. + * + * Parameters : + * 1 : iob = Destination buffer. + * 2 : buffer_limit = Limit to which the destination may grow + * 3 : n = number of bytes to be added + * + * Returns : TRUE if the given iob can handle given number of bytes + * FALSE buffer limit will be exceeded + * + *********************************************************************/ +int can_add_to_iob(const struct iob *iob, const size_t buffer_limit, size_t n) +{ + return ((size_t)(iob->eod - iob->buf) + n + 1) > buffer_limit ? FALSE : TRUE; +} + /********************************************************************* * * Function : add_to_iob @@ -308,7 +329,7 @@ long flush_iob(jb_socket fd, struct iob *iob, unsigned int delay) * or buffer limit reached. * *********************************************************************/ -jb_err add_to_iob(struct iob *iob, const size_t buffer_limit, char *src, long n) +jb_err add_to_iob(struct iob *iob, const size_t buffer_limit, const char *src, long n) { size_t used, offset, need; char *p; @@ -1190,8 +1211,8 @@ static void enforce_header_order(struct list *headers, const struct list *ordere } list_remove_all(headers); - list_duplicate(headers, new_headers); - list_remove_all(new_headers); + headers->first = new_headers->first; + headers->last = new_headers->last; return; } @@ -1270,7 +1291,9 @@ jb_err sed(struct client_state *csp, int filter_server_headers) f++; } - if (!filter_server_headers && !list_is_empty(csp->config->ordered_client_headers)) + if (!filter_server_headers && + !list_is_empty(csp->config->ordered_client_headers) && + csp->headers->first->str != NULL) { enforce_header_order(csp->headers, csp->config->ordered_client_headers); } @@ -1325,9 +1348,11 @@ jb_err sed_https(struct client_state *csp) csp->flags |= CSP_FLAG_CLIENT_HEADER_PARSING_DONE; /* - * Update the last header which may have changed - * due to header additions, + * Update the https headers list which may have + * been modified due to header additions or header + * reordering. */ + csp->https_headers->first = csp->headers->first; csp->https_headers->last = csp->headers->last; csp->headers->first = headers.first; @@ -1488,7 +1513,7 @@ static jb_err header_tagger(struct client_state *csp, char *header) if (NULL == joblist) { - log_error(LOG_LEVEL_RE_FILTER, + log_error(LOG_LEVEL_TAGGING, "Tagger %s has empty joblist. Nothing to do.", b->name); continue; } @@ -1535,14 +1560,14 @@ static jb_err header_tagger(struct client_state *csp, char *header) * no one would do it intentionally. */ freez(tag); - log_error(LOG_LEVEL_INFO, + log_error(LOG_LEVEL_TAGGING, "Tagger \'%s\' created an empty tag. Ignored.", b->name); continue; } if (list_contains_item(csp->action->multi[ACTION_MULTI_SUPPRESS_TAG], tag)) { - log_error(LOG_LEVEL_HEADER, + log_error(LOG_LEVEL_TAGGING, "Tagger \'%s\' didn't add tag \'%s\': suppressed", b->name, tag); freez(tag); @@ -1575,7 +1600,7 @@ static jb_err header_tagger(struct client_state *csp, char *header) action_message = "No action bits update necessary."; } - log_error(LOG_LEVEL_HEADER, + log_error(LOG_LEVEL_TAGGING, "Tagger \'%s\' added tag \'%s\'. %s", b->name, tag, action_message); } @@ -1583,7 +1608,7 @@ static jb_err header_tagger(struct client_state *csp, char *header) else { /* XXX: Is this log-worthy? */ - log_error(LOG_LEVEL_HEADER, + log_error(LOG_LEVEL_TAGGING, "Tagger \'%s\' didn't add tag \'%s\'. Tag already present", b->name, tag); } @@ -1672,7 +1697,8 @@ static jb_err filter_header(struct client_state *csp, char **header) if (NULL == joblist) { - log_error(LOG_LEVEL_RE_FILTER, "Filter %s has empty joblist. Nothing to do.", b->name); + log_error(LOG_LEVEL_RE_FILTER, + "Filter %s has empty joblist. Nothing to do.", b->name); continue; } @@ -1686,7 +1712,8 @@ static jb_err filter_header(struct client_state *csp, char **header) if (0 < matches) { current_hits += matches; - log_error(LOG_LEVEL_HEADER, "Transforming \"%s\" to \"%s\"", *header, newheader); + log_error(LOG_LEVEL_HEADER, + "Transforming \"%s\" to \"%s\"", *header, newheader); freez(*header); *header = newheader; } @@ -1698,7 +1725,8 @@ static jb_err filter_header(struct client_state *csp, char **header) else { /* RegEx failure */ - log_error(LOG_LEVEL_ERROR, "Filtering \'%s\' with \'%s\' didn't work out: %s", + log_error(LOG_LEVEL_ERROR, + "Filtering \'%s\' with \'%s\' didn't work out: %s", *header, b->name, pcrs_strerror(matches)); if (newheader != NULL) { @@ -2003,10 +2031,7 @@ static jb_err get_content_length(const char *header_value, unsigned long long *l * * Parameters : * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : header = On input, pointer to header to modify. - * On output, pointer to the modified header, or NULL - * to remove the header. This function frees the - * original string if necessary. + * 2 : header = pointer to the Content-Length header * * Returns : JB_ERR_OK on success, or * JB_ERR_MEMORY on out-of-memory error. @@ -2617,6 +2642,37 @@ static jb_err server_adjust_content_encoding(struct client_state *csp, char **he #endif /* defined(FEATURE_ZLIB) */ +/********************************************************************* + * + * Function : header_adjust_content_length + * + * Description : Replace given header with new Content-Length header. + * + * Parameters : + * 1 : header = On input, pointer to header to modify. + * On output, pointer to the modified header, or NULL + * to remove the header. This function frees the + * original string if necessary. + * 2 : content_length = content length value to set + * + * Returns : JB_ERR_OK on success, or + * JB_ERR_MEMORY on out-of-memory error. + * + *********************************************************************/ +jb_err header_adjust_content_length(char **header, size_t content_length) +{ + const size_t header_length = 50; + freez(*header); + *header = malloc(header_length); + if (*header == NULL) + { + return JB_ERR_MEMORY; + } + create_content_length_header(content_length, *header, header_length); + return JB_ERR_OK; +} + + /********************************************************************* * * Function : server_adjust_content_length @@ -2640,14 +2696,10 @@ static jb_err server_adjust_content_length(struct client_state *csp, char **head /* Regenerate header if the content was modified. */ if (csp->flags & CSP_FLAG_MODIFIED) { - const size_t header_length = 50; - freez(*header); - *header = malloc(header_length); - if (*header == NULL) + if (JB_ERR_OK != header_adjust_content_length(header, csp->content_length)) { return JB_ERR_MEMORY; } - create_content_length_header(csp->content_length, *header, header_length); log_error(LOG_LEVEL_HEADER, "Adjusted Content-Length to %llu", csp->content_length); } @@ -4852,6 +4904,10 @@ static jb_err handle_conditional_hide_referrer_parameter(char **header, referer[hostlength+17] = '\0'; } referer_url = strstr(referer, "http://"); + if (NULL == referer_url) + { + referer_url = strstr(referer, "https://"); + } if ((NULL == referer_url) || (NULL == strstr(referer_url, host))) { /* Host has changed, Referer is invalid or a https URL. */