X-Git-Url: http://www.privoxy.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=cgiedit.c;h=fb268c2c30dee229383a8363bde6e328d9b11e48;hb=740f1bb7087065eeb921792711bba4db3277cef8;hp=5058dd7c0877ff2855d7e5ff5ec8082ad91dde0f;hpb=a039d7a80f93ae61f41a329695189c50002a1c89;p=privoxy.git diff --git a/cgiedit.c b/cgiedit.c index 5058dd7c..fb268c2c 100644 --- a/cgiedit.c +++ b/cgiedit.c @@ -1,4 +1,4 @@ -const char cgiedit_rcs[] = "$Id: cgiedit.c,v 1.46 2006/12/27 18:44:52 fabiankeil Exp $"; +const char cgiedit_rcs[] = "$Id: cgiedit.c,v 1.49 2007/03/20 15:16:34 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/cgiedit.c,v $ @@ -15,7 +15,7 @@ const char cgiedit_rcs[] = "$Id: cgiedit.c,v 1.46 2006/12/27 18:44:52 fabiankeil * * Stick to the short names in this file for consistency. * - * Copyright : Written by and Copyright (C) 2001 the SourceForge + * Copyright : Written by and Copyright (C) 2001-2007 the SourceForge * Privoxy team. http://www.privoxy.org/ * * Based on the Internet Junkbuster originally written @@ -42,6 +42,18 @@ const char cgiedit_rcs[] = "$Id: cgiedit.c,v 1.46 2006/12/27 18:44:52 fabiankeil * * Revisions : * $Log: cgiedit.c,v $ + * Revision 1.49 2007/03/20 15:16:34 fabiankeil + * Use dedicated header filter actions instead of abusing "filter". + * Replace "filter-client-headers" and "filter-client-headers" + * with "server-header-filter" and "client-header-filter". + * + * Revision 1.48 2007/02/13 14:35:25 fabiankeil + * Replace hash escaping code to prevent + * crashes, memory and file corruption. + * + * Revision 1.47 2006/12/28 18:04:25 fabiankeil + * Fixed gcc43 conversion warnings. + * * Revision 1.46 2006/12/27 18:44:52 fabiankeil * Stop shadowing string.h's index(). * @@ -1013,29 +1025,44 @@ jb_err edit_write_file(struct editable_file * file) assert(numhash > 0); /* Allocate new memory for string */ - len = strlen(cur_line->unprocessed); - if (NULL == (str = malloc(len + 1 + (size_t)numhash))) + len = strlen(cur_line->unprocessed) + (size_t)numhash; + if (NULL == (str = malloc(len + 1))) { /* Uh oh, just trashed file! */ fclose(fp); return JB_ERR_MEMORY; } - /* Loop through string from end */ - src = cur_line->unprocessed + len; - dest = str + len + numhash; - for ( ; len >= 0; len--) + /* Copy string but quote hashes */ + src = cur_line->unprocessed; + dest = str; + while (*src) { - if ((*dest-- = *src--) == '#') + if (*src == '#') { - *dest-- = '\\'; + *dest++ = '\\'; numhash--; assert(numhash >= 0); } + *dest++ = *src++; } + *dest = '\0'; + assert(numhash == 0); - assert(src + 1 == cur_line->unprocessed); - assert(dest + 1 == str); + assert(strlen(str) == len); + assert(str == dest - len); + assert(src - len <= cur_line->unprocessed); + + if ((strlen(str) != len) || (numhash != 0)) + { + /* + * Escaping didn't work as expected, go spread the news. + * Only reached in non-debugging builds. + */ + log_error(LOG_LEVEL_ERROR, + "Looks like hash escaping failed. %s might be corrupted now.", + file->filename); + } if (fputs(str, fp) < 0) { @@ -3088,13 +3115,19 @@ jb_err cgi_edit_actions_for_url(struct client_state *csp, } if (0 == have_filters) + { err = map(exports, "filter-params", 1, "", 1); + } else { - /* We have some entries in the filter list */ - char * result; + /* + * List available filters and their settings. + */ + char *content_filter_params; + char *server_header_filter_params; + char *client_header_filter_params; + char *filter_template; int filter_identifier = 0; - char * filter_template; err = template_load(csp, &filter_template, "edit-actions-for-url-filter", 0); if (err) @@ -3110,7 +3143,9 @@ jb_err cgi_edit_actions_for_url(struct client_state *csp, err = template_fill(&filter_template, exports); - result = strdup(""); + content_filter_params = strdup(""); + server_header_filter_params = strdup(""); + client_header_filter_params = strdup(""); for (i = 0; i < MAX_AF_FILES; i++) { @@ -3120,12 +3155,49 @@ jb_err cgi_edit_actions_for_url(struct client_state *csp, for (;(!err) && (filter_group != NULL); filter_group = filter_group->next) { char current_mode = 'x'; + char number[20]; + int multi_action_index = 0; struct list_entry *filter_name; - char * this_line; struct map *line_exports; - char number[20]; + char *this_line; + char *filter_type; + char *abbr_filter_type; + char *anchor; + char **current_params; - filter_name = cur_line->data.action->multi_add[ACTION_MULTI_FILTER]->first; + switch (filter_group->type) + { + case FT_CONTENT_FILTER: + /* XXX: Should we call it content-filter instead? */ + filter_type = "filter"; + abbr_filter_type = "F"; + multi_action_index = ACTION_MULTI_FILTER; + anchor = "FILTER"; + current_params = &content_filter_params; + break; + case FT_SERVER_HEADER_FILTER: + filter_type = "server-header-filter"; + abbr_filter_type = "S"; + multi_action_index = ACTION_MULTI_SERVER_HEADER_FILTER; + current_params = &server_header_filter_params; + anchor = "SERVER-HEADER-FILTER"; /* XXX: no documentation available yet */ + break; + case FT_CLIENT_HEADER_FILTER: + filter_type = "client-header-filter"; + abbr_filter_type = "C"; + multi_action_index = ACTION_MULTI_CLIENT_HEADER_FILTER; + current_params = &client_header_filter_params; + anchor = "CLIENT-HEADER-FILTER"; /* XXX: no documentation available yet */ + break; + default: + log_error(LOG_LEVEL_FATAL, + "cgi_edit_actions_for_url: Unknown filter type: %u for filter %s.", + filter_group->type, filter_group->name); + /* Not reached. */ + } + assert(multi_action_index); + + filter_name = cur_line->data.action->multi_add[multi_action_index]->first; while ((filter_name != NULL) && (0 != strcmp(filter_group->name, filter_name->str))) { @@ -3138,7 +3210,7 @@ jb_err cgi_edit_actions_for_url(struct client_state *csp, } else { - filter_name = cur_line->data.action->multi_remove[ACTION_MULTI_FILTER]->first; + filter_name = cur_line->data.action->multi_remove[multi_action_index]->first; while ((filter_name != NULL) && (0 != strcmp(filter_group->name, filter_name->str))) { @@ -3158,7 +3230,7 @@ jb_err cgi_edit_actions_for_url(struct client_state *csp, if (line_exports == NULL) { err = JB_ERR_MEMORY; - freez(result); + freez(*current_params); /* XXX: really necessary? */ } else { @@ -3166,6 +3238,9 @@ jb_err cgi_edit_actions_for_url(struct client_state *csp, if (!err) err = map(line_exports, "name", 1, filter_group->name, 1); if (!err) err = map(line_exports, "description", 1, filter_group->description, 1); if (!err) err = map_radio(line_exports, "this-filter", "ynx", current_mode); + if (!err) err = map(line_exports, "filter-type", 1, filter_type, 1); + if (!err) err = map(line_exports, "abbr-filter-type", 1, abbr_filter_type, 1); + if (!err) err = map(line_exports, "anchor", 1, anchor, 1); this_line = NULL; if (!err) @@ -3174,7 +3249,7 @@ jb_err cgi_edit_actions_for_url(struct client_state *csp, if (this_line == NULL) err = JB_ERR_MEMORY; } if (!err) err = template_fill(&this_line, line_exports); - string_join(&result, this_line); + string_join(current_params, this_line); free_map(line_exports); } @@ -3183,13 +3258,14 @@ jb_err cgi_edit_actions_for_url(struct client_state *csp, } freez(filter_template); - if (!err) - { - err = map(exports, "filter-params", 1, result, 0); - } - else + if (!err) err = map(exports, "content-filter-params", 1, content_filter_params, 0); + if (!err) err = map(exports, "server-header-filter-params", 1, server_header_filter_params, 0); + if (!err) err = map(exports, "client-header-filter-params", 1, client_header_filter_params, 0); + if (err) { - freez(result); + freez(content_filter_params); + freez(server_header_filter_params); + freez(client_header_filter_params); } } @@ -3331,14 +3407,25 @@ jb_err cgi_edit_actions_submit(struct client_state *csp, { char key_value[30]; char key_name[30]; + char key_type[30]; const char *name; - char value; + char value; /* + * Filter state. Valid states are: 'Y' (active), + * 'N' (inactive) and 'X' (no change). + * XXX: bad name. + */ + char type; /* + * Abbreviated filter type. Valid types are: 'F' (content filter), + * 'S' (server-header filter) and 'C' (client-header filter). + */ + int multi_action_index = 0; /* Generate the keys */ snprintf(key_value, sizeof(key_value), "filter_r%x", filter_identifier); - key_value[sizeof(key_value) - 1] = '\0'; + key_value[sizeof(key_value) - 1] = '\0'; /* XXX: Why? */ snprintf(key_name, sizeof(key_name), "filter_n%x", filter_identifier); - key_name[sizeof(key_name) - 1] = '\0'; + key_name[sizeof(key_name) - 1] = '\0'; /* XXX: Why? */ + snprintf(key_type, sizeof(key_type), "filter_t%x", filter_identifier); err = get_string_param(parameters, key_name, &name); if (err) break; @@ -3349,26 +3436,45 @@ jb_err cgi_edit_actions_submit(struct client_state *csp, break; } + type = get_char_param(parameters, key_type); + switch (type) + { + case 'F': + multi_action_index = ACTION_MULTI_FILTER; + break; + case 'S': + multi_action_index = ACTION_MULTI_SERVER_HEADER_FILTER; + break; + case 'C': + multi_action_index = ACTION_MULTI_CLIENT_HEADER_FILTER; + break; + default: + log_error(LOG_LEVEL_ERROR, + "Unknown filter type: %c for filter %s. Filter ignored.", type, name); + continue; + } + assert(multi_action_index); + value = get_char_param(parameters, key_value); if (value == 'Y') { - list_remove_item(cur_line->data.action->multi_add[ACTION_MULTI_FILTER], name); - if (!err) err = enlist(cur_line->data.action->multi_add[ACTION_MULTI_FILTER], name); - list_remove_item(cur_line->data.action->multi_remove[ACTION_MULTI_FILTER], name); + list_remove_item(cur_line->data.action->multi_add[multi_action_index], name); + if (!err) err = enlist(cur_line->data.action->multi_add[multi_action_index], name); + list_remove_item(cur_line->data.action->multi_remove[multi_action_index], name); } else if (value == 'N') { - list_remove_item(cur_line->data.action->multi_add[ACTION_MULTI_FILTER], name); - if (!cur_line->data.action->multi_remove_all[ACTION_MULTI_FILTER]) + list_remove_item(cur_line->data.action->multi_add[multi_action_index], name); + if (!cur_line->data.action->multi_remove_all[multi_action_index]) { - list_remove_item(cur_line->data.action->multi_remove[ACTION_MULTI_FILTER], name); - if (!err) err = enlist(cur_line->data.action->multi_remove[ACTION_MULTI_FILTER], name); + list_remove_item(cur_line->data.action->multi_remove[multi_action_index], name); + if (!err) err = enlist(cur_line->data.action->multi_remove[multi_action_index], name); } } else if (value == 'X') { - list_remove_item(cur_line->data.action->multi_add[ACTION_MULTI_FILTER], name); - list_remove_item(cur_line->data.action->multi_remove[ACTION_MULTI_FILTER], name); + list_remove_item(cur_line->data.action->multi_add[multi_action_index], name); + list_remove_item(cur_line->data.action->multi_remove[multi_action_index], name); } }