X-Git-Url: http://www.privoxy.org/gitweb/?a=blobdiff_plain;f=parsers.c;h=b40154226e9afa8518a77570fd1de0099d8bce3c;hb=c46413a31172a46ad4b522a614b130a202cc6b2a;hp=7dbaf028c050a2524ebd5303915197f266500320;hpb=09affc2a8063be4014aba82b095fb7d225b12016;p=privoxy.git diff --git a/parsers.c b/parsers.c index 7dbaf028..b4015422 100644 --- a/parsers.c +++ b/parsers.c @@ -1,23 +1,11 @@ -const char parsers_rcs[] = "$Id: parsers.c,v 1.228 2011/09/04 11:31:17 fabiankeil Exp $"; +const char parsers_rcs[] = "$Id: parsers.c,v 1.242 2012/03/04 11:51:25 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/parsers.c,v $ * * Purpose : Declares functions to parse/crunch headers and pages. - * Functions declared include: - * `add_to_iob', `client_cookie_adder', `client_from', - * `client_referrer', `client_send_cookie', `client_ua', - * `client_uagent', `client_x_forwarded', - * `client_x_forwarded_adder', `client_xtra_adder', - * `content_type', `crumble', `destroy_list', `enlist', - * `flush_socket', ``get_header', `sed', `filter_header' - * `server_content_encoding', `server_content_disposition', - * `server_last_modified', `client_accept_language', - * `crunch_client_header', `client_if_modified_since', - * `client_if_none_match', `get_destination_from_headers', - * `parse_header_time', `decompress_iob' and `server_set_cookie'. - * - * Copyright : Written by and Copyright (C) 2001-2009 the + * + * Copyright : Written by and Copyright (C) 2001-2011 the * Privoxy team. http://www.privoxy.org/ * * Based on the Internet Junkbuster originally written @@ -104,19 +92,6 @@ const char parsers_rcs[] = "$Id: parsers.c,v 1.228 2011/09/04 11:31:17 fabiankei const char parsers_h_rcs[] = PARSERS_H_VERSION; -/* Fix a problem with Solaris. There should be no effect on other - * platforms. - * Solaris's isspace() is a macro which uses its argument directly - * as an array index. Therefore we need to make sure that high-bit - * characters generate +ve values, and ideally we also want to make - * the argument match the declared parameter type of "int". - * - * Why did they write a character function that can't take a simple - * "char" argument? Doh! - */ -#define ijb_isupper(__X) isupper((int)(unsigned char)(__X)) -#define ijb_tolower(__X) tolower((int)(unsigned char)(__X)) - static char *get_header_line(struct iob *iob); static jb_err scan_headers(struct client_state *csp); static jb_err header_tagger(struct client_state *csp, char *header); @@ -252,7 +227,6 @@ static const add_header_func_ptr add_client_headers[] = { client_host_adder, client_x_forwarded_for_adder, client_xtra_adder, - /* Temporarily disabled: client_accept_encoding_adder, */ client_connection_header_adder, NULL }; @@ -796,11 +770,11 @@ static void normalize_lws(char *header) while (*p != '\0') { - if (ijb_isspace(*p) && ijb_isspace(*(p+1))) + if (privoxy_isspace(*p) && privoxy_isspace(*(p+1))) { char *q = p+1; - while (ijb_isspace(*q)) + while (privoxy_isspace(*q)) { q++; } @@ -833,7 +807,7 @@ static void normalize_lws(char *header) } p = strchr(header, ':'); - if ((p != NULL) && (p != header) && ijb_isspace(*(p-1))) + if ((p != NULL) && (p != header) && privoxy_isspace(*(p-1))) { /* * There's still space before the colon. @@ -1008,7 +982,7 @@ char *get_header_value(const struct list *header_list, const char *header_name) * Found: return pointer to start of value */ ret = cur_entry->str + length; - while (*ret && ijb_isspace(*ret)) ret++; + while (*ret && privoxy_isspace(*ret)) ret++; return ret; } } @@ -1570,8 +1544,7 @@ static jb_err filter_header(struct client_state *csp, char **header) * to remove the header. This function frees the * original string if necessary. * - * Returns : JB_ERR_OK on success, or - * JB_ERR_MEMORY on out-of-memory error. + * Returns : JB_ERR_OK on success. * *********************************************************************/ static jb_err server_connection(struct client_state *csp, char **header) @@ -1598,11 +1571,7 @@ static jb_err server_connection(struct client_state *csp, char **header) { char *old_header = *header; - *header = strdup("Connection: close"); - if (header == NULL) - { - return JB_ERR_MEMORY; - } + *header = strdup_or_die("Connection: close"); log_error(LOG_LEVEL_HEADER, "Replaced: \'%s\' with \'%s\'", old_header, *header); freez(old_header); } @@ -1832,8 +1801,7 @@ static jb_err client_save_content_length(struct client_state *csp, char **header * to remove the header. This function frees the * original string if necessary. * - * Returns : JB_ERR_OK on success, or - * JB_ERR_MEMORY on out-of-memory error. + * Returns : JB_ERR_OK on success. * *********************************************************************/ static jb_err client_connection(struct client_state *csp, char **header) @@ -1850,16 +1818,17 @@ static jb_err client_connection(struct client_state *csp, char **header) log_error(LOG_LEVEL_HEADER, "Removing \'%s\' to imply keep-alive.", *header); freez(*header); + /* + * While we imply keep-alive to the server, + * we have to remember that the client didn't. + */ + csp->flags &= ~CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE; } else { char *old_header = *header; - *header = strdup("Connection: keep-alive"); - if (header == NULL) - { - return JB_ERR_MEMORY; - } + *header = strdup_or_die("Connection: keep-alive"); log_error(LOG_LEVEL_HEADER, "Replaced: \'%s\' with \'%s\'", old_header, *header); freez(old_header); @@ -1887,11 +1856,7 @@ static jb_err client_connection(struct client_state *csp, char **header) { char *old_header = *header; - *header = strdup(connection_close); - if (header == NULL) - { - return JB_ERR_MEMORY; - } + *header = strdup_or_die(connection_close); log_error(LOG_LEVEL_HEADER, "Replaced: \'%s\' with \'%s\'", old_header, *header); freez(old_header); @@ -2045,7 +2010,7 @@ static jb_err server_content_type(struct client_state *csp, char **header) if ((csp->content_type & CT_TEXT) || (csp->action->flags & ACTION_FORCE_TEXT_MODE)) { freez(*header); - *header = strdup("Content-Type: "); + *header = strdup_or_die("Content-Type: "); string_append(header, csp->action->string[ACTION_STRING_CONTENT_TYPE]); if (header == NULL) @@ -2468,7 +2433,6 @@ static jb_err server_content_disposition(struct client_state *csp, char **header static jb_err server_last_modified(struct client_state *csp, char **header) { const char *newval; - char buf[BUFFER_SIZE]; time_t last_modified; char newheader[50]; @@ -2497,6 +2461,7 @@ static jb_err server_last_modified(struct client_state *csp, char **header) /* * Setting Last-Modified Header to now. */ + char buf[30]; get_http_time(0, buf, sizeof(buf)); freez(*header); *header = strdup("Last-Modified: "); @@ -3149,16 +3114,9 @@ static jb_err client_host(struct client_state *csp, char **header) *csp->http->hostport == ' ' || *csp->http->hostport == '\0') { - if (NULL == (p = strdup((*header)+6))) - { - return JB_ERR_MEMORY; - } + p = strdup_or_die((*header)+6); chomp(p); - if (NULL == (q = strdup(p))) - { - freez(p); - return JB_ERR_MEMORY; - } + q = strdup_or_die(p); freez(csp->http->hostport); csp->http->hostport = p; @@ -3476,36 +3434,6 @@ static jb_err client_host_adder(struct client_state *csp) } -#if 0 -/********************************************************************* - * - * Function : client_accept_encoding_adder - * - * Description : Add an Accept-Encoding header to the client's request - * that disables compression if the action applies, and - * the header is not already there. Called from `sed'. - * Note: For HTTP/1.0, the absence of the header is enough. - * - * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * - * Returns : JB_ERR_OK on success, or - * JB_ERR_MEMORY on out-of-memory error. - * - *********************************************************************/ -static jb_err client_accept_encoding_adder(struct client_state *csp) -{ - if ( ((csp->action->flags & ACTION_NO_COMPRESSION) != 0) - && (!strcmpic(csp->http->ver, "HTTP/1.1")) ) - { - return enlist_unique(csp->headers, "Accept-Encoding: identity;q=1.0, *;q=0", 16); - } - - return JB_ERR_OK; -} -#endif - - /********************************************************************* * * Function : client_xtra_adder @@ -3809,7 +3737,7 @@ static jb_err server_set_cookie(struct client_state *csp, char **header) cur_tag = *header + 11; /* skip whitespace between "Set-Cookie:" and value */ - while (*cur_tag && ijb_isspace(*cur_tag)) + while (*cur_tag && privoxy_isspace(*cur_tag)) { cur_tag++; } @@ -3825,7 +3753,7 @@ static jb_err server_set_cookie(struct client_state *csp, char **header) next_tag++; /* skip whitespace ";" and start of tag */ - while (*next_tag && ijb_isspace(*next_tag)) + while (*next_tag && privoxy_isspace(*next_tag)) { next_tag++; } @@ -4008,13 +3936,18 @@ int strclean(char *string, const char *substring) static jb_err parse_header_time(const char *header_time, time_t *result) { struct tm gmt; - static const char *time_formats[] = { + /* + * Checking for two-digit years first in an + * attempt to work around GNU libc's strptime() + * reporting negative year values when using %Y. + */ + static const char * const time_formats[] = { + /* Tue, 02-Jun-37 20:00:00 */ + "%a, %d-%b-%y %H:%M:%S", /* Tue, 02 Jun 2037 20:00:00 */ "%a, %d %b %Y %H:%M:%S", /* Tue, 02-Jun-2037 20:00:00 */ "%a, %d-%b-%Y %H:%M:%S", - /* Tue, 02-Jun-37 20:00:00 */ - "%a, %d-%b-%y %H:%M:%S", /* Tuesday, 02-Jun-2037 20:00:00 */ "%A, %d-%b-%Y %H:%M:%S", /* Tuesday Jun 02 20:00:00 2037 */ @@ -4022,16 +3955,24 @@ static jb_err parse_header_time(const char *header_time, time_t *result) }; unsigned int i; - /* - * Zero out gmt to prevent time zone offsets. - * Documented to be required for GNU libc. - */ - memset(&gmt, 0, sizeof(gmt)); - for (i = 0; i < SZ(time_formats); i++) { + /* + * Zero out gmt to prevent time zone offsets. + * Documented to be required for GNU libc. + */ + memset(&gmt, 0, sizeof(gmt)); + if (NULL != strptime(header_time, time_formats[i], &gmt)) { + /* Sanity check for GNU libc. */ + if (gmt.tm_year < 0) + { + log_error(LOG_LEVEL_HEADER, + "Failed to parse '%s' using '%s'. Moving on.", + header_time, time_formats[i]); + continue; + } *result = timegm(&gmt); return JB_ERR_OK; } @@ -4058,7 +3999,7 @@ static jb_err parse_header_time(const char *header_time, time_t *result) * the "Host:" header) * 2 : http = storage for the result (host, port and hostport). * - * Returns : JB_ERR_MEMORY in case of memory problems, + * Returns : JB_ERR_MEMORY (or terminates) in case of memory problems, * JB_ERR_PARSE if the host header couldn't be found, * JB_ERR_OK otherwise. * @@ -4077,19 +4018,9 @@ jb_err get_destination_from_headers(const struct list *headers, struct http_requ return JB_ERR_PARSE; } - p = strdup(host); - if (NULL == p) - { - log_error(LOG_LEVEL_ERROR, "Out of memory while parsing \"Host:\" header"); - return JB_ERR_MEMORY; - } + p = strdup_or_die(host); chomp(p); - if (NULL == (q = strdup(p))) - { - freez(p); - log_error(LOG_LEVEL_ERROR, "Out of memory while parsing \"Host:\" header"); - return JB_ERR_MEMORY; - } + q = strdup_or_die(p); freez(http->hostport); http->hostport = p; @@ -4130,7 +4061,7 @@ jb_err get_destination_from_headers(const struct list *headers, struct http_requ * Function : create_forged_referrer * * Description : Helper for client_referrer to forge a referer as - * 'http://[hostname:port/' to fool stupid + * 'http://hostname[:port]/' to fool stupid * checks for in-site links * * Parameters : @@ -4221,16 +4152,10 @@ static jb_err create_fake_referrer(char **header, const char *fake_referrer) static jb_err handle_conditional_hide_referrer_parameter(char **header, const char *host, const int parameter_conditional_block) { - char *referer = strdup(*header); + char *referer = strdup_or_die(*header); const size_t hostlength = strlen(host); const char *referer_url = NULL; - if (NULL == referer) - { - freez(*header); - return JB_ERR_MEMORY; - } - /* referer begins with 'Referer: http[s]://' */ if ((hostlength+17) < strlen(referer)) {