X-Git-Url: http://www.privoxy.org/gitweb/?a=blobdiff_plain;f=cgiedit.c;h=5058dd7c0877ff2855d7e5ff5ec8082ad91dde0f;hb=cf70a45c4266c4a246c556bafa3fe7cdd46f6ef9;hp=c447baa3dca52796a077741947eecd6b21e06f27;hpb=02165000f2941460fac686a76ec31f555285a653;p=privoxy.git diff --git a/cgiedit.c b/cgiedit.c index c447baa3..5058dd7c 100644 --- a/cgiedit.c +++ b/cgiedit.c @@ -1,4 +1,4 @@ -const char cgiedit_rcs[] = "$Id: cgiedit.c,v 1.39 2002/05/12 21:39:15 jongfoster Exp $"; +const char cgiedit_rcs[] = "$Id: cgiedit.c,v 1.46 2006/12/27 18:44:52 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/cgiedit.c,v $ @@ -42,6 +42,79 @@ const char cgiedit_rcs[] = "$Id: cgiedit.c,v 1.39 2002/05/12 21:39:15 jongfoster * * Revisions : * $Log: cgiedit.c,v $ + * Revision 1.46 2006/12/27 18:44:52 fabiankeil + * Stop shadowing string.h's index(). + * + * Revision 1.45 2006/12/21 12:57:48 fabiankeil + * Add config option "split-large-forms" + * to work around the browser bug reported + * in BR #1570678. + * + * Revision 1.44 2006/12/09 13:49:16 fabiankeil + * Fix configure option --disable-toggle. + * Thanks to Peter Thoenen for reporting this. + * + * Revision 1.43 2006/07/18 14:48:45 david__schmidt + * Reorganizing the repository: swapping out what was HEAD (the old 3.1 branch) + * with what was really the latest development (the v_3_0_branch branch) + * + * Revision 1.41.2.12 2006/01/30 15:16:25 david__schmidt + * Remove a little residual debugging info + * + * Revision 1.41.2.11 2006/01/29 23:10:56 david__schmidt + * Multiple filter file support + * + * Revision 1.41.2.10 2005/07/04 03:13:43 david__schmidt + * Undo some damaging memory leak patches + * + * Revision 1.41.2.9 2005/07/04 00:31:04 david__schmidt + * Removing a double free + * + * Revision 1.41.2.8 2005/05/07 21:50:54 david__schmidt + * A few memory leaks plugged (mostly on error paths) + * + * Revision 1.41.2.7 2004/02/17 13:30:23 oes + * Moved cgi_error_disabled() from cgiedit.c to + * cgi.c to re-enable build with --disable-editor. + * Fixes Bug #892744. Thanks to Matthew Fischer + * for spotting. + * + * Revision 1.41.2.6 2003/12/18 08:13:48 oes + * One line lost in last commit + * + * Revision 1.41.2.5 2003/12/17 16:33:47 oes + * - All edit functions that redirect back to the list page + * now use cgi_redirect + * - All redirects now contain useless parameter "foo", whose + * value are raw seconds since epoch, in order to force + * Opera and Konqueror to properly reload the list. Closes + * bug #859993 + * + * Revision 1.41.2.4 2003/03/11 11:53:59 oes + * Cosmetic: Renamed cryptic variable + * + * Revision 1.41.2.3 2002/11/12 15:01:41 oes + * Fix: Don't free uninitialized struct editable_file + * + * Revision 1.41.2.2 2002/08/05 20:02:59 oes + * Bugfix: "Insert new section at top" did not work properly if first non-comment line in file was of type FILE_LINE_ACTION + * + * Revision 1.41.2.1 2002/08/02 12:43:14 oes + * Fixed bug #588514: first_time now set on a per-string basis in actions_from_radio; javascriptify now called on copies + * + * Revision 1.41 2002/05/21 19:09:45 oes + * - Made Add/Edit/Remove URL Submit and Cancel + * buttons jump back to relevant section in eal + * - Bugfix: remove-url-form needs p export + * + * Revision 1.40 2002/05/19 11:34:35 jongfoster + * Handling read-only actions files better - report the actual + * error, not "Out of memory"! + * + * Bug report: + * http://sourceforge.net/tracker/index.php?func=detail + * &aid=557905&group_id=11118&atid=111118 + * * Revision 1.39 2002/05/12 21:39:15 jongfoster * - Adding Doxygen-style comments to structures and #defines. * - Correcting function comments @@ -272,8 +345,10 @@ const char cgiedit_rcs[] = "$Id: cgiedit.c,v 1.39 2002/05/12 21:39:15 jongfoster #include "miscutil.h" #include "errlog.h" #include "loaders.h" +#ifdef FEATURE_TOGGLE +/* loadcfg.h is for global_toggle_state only */ #include "loadcfg.h" -/* loadcfg.h is for g_bToggleIJB only */ +#endif /* def FEATURE_TOGGLE */ #include "urlmatch.h" const char cgiedit_h_rcs[] = CGIEDIT_H_VERSION; @@ -433,8 +508,6 @@ jb_err cgi_error_file(struct client_state *csp, jb_err cgi_error_file_read_only(struct client_state *csp, struct http_response *rsp, const char *filename); -jb_err cgi_error_disabled(struct client_state *csp, - struct http_response *rsp); /* Internal arbitrary config file support functions */ static jb_err edit_read_file_lines(FILE *fp, struct file_line ** pfile, int *newline); @@ -478,6 +551,34 @@ static jb_err map_copy_parameter_url(struct map *out, const char *name); #endif /* unused function */ +/* Internal convenience functions */ +static char *section_target(const unsigned sectionid); + +/********************************************************************* + * + * Function : section_target + * + * Description : Given an unsigned (section id) n, produce a dynamically + * allocated string of the form #l, for use in link + * targets. + * + * Parameters : + * 1 : sectionid = start line number of section + * + * Returns : String with link target, or NULL if out of + * memory + * + *********************************************************************/ +static char *section_target(const unsigned sectionid) +{ + char buf[30]; + + snprintf(buf, 30, "#l%d", sectionid); + return(strdup(buf)); + +} + + /********************************************************************* * * Function : map_copy_parameter_html @@ -607,6 +708,7 @@ jb_err cgi_edit_actions_url_form(struct client_state *csp, struct editable_file * file; struct file_line * cur_line; unsigned line_number; + unsigned section_start_line_number = 0; jb_err err; assert(csp); @@ -635,6 +737,10 @@ jb_err cgi_edit_actions_url_form(struct client_state *csp, for (line_number = 1; (cur_line != NULL) && (line_number < patternid); line_number++) { + if (cur_line->type == FILE_LINE_ACTION) + { + section_start_line_number = line_number; + } cur_line = cur_line->next; } @@ -658,6 +764,7 @@ jb_err cgi_edit_actions_url_form(struct client_state *csp, if (!err) err = map(exports, "v", 1, file->version_str, 1); if (!err) err = map(exports, "p", 1, url_encode(lookup(parameters, "p")), 0); if (!err) err = map(exports, "u", 1, html_encode(cur_line->unprocessed), 0); + if (!err) err = map(exports, "jumptarget", 1, section_target(section_start_line_number), 0); edit_free_file(file); @@ -761,6 +868,7 @@ jb_err cgi_edit_actions_remove_url_form(struct client_state *csp, struct editable_file * file; struct file_line * cur_line; unsigned line_number; + unsigned section_start_line_number = 0; jb_err err; assert(csp); @@ -789,6 +897,10 @@ jb_err cgi_edit_actions_remove_url_form(struct client_state *csp, for (line_number = 1; (cur_line != NULL) && (line_number < patternid); line_number++) { + if (cur_line->type == FILE_LINE_ACTION) + { + section_start_line_number = line_number; + } cur_line = cur_line->next; } @@ -810,8 +922,9 @@ jb_err cgi_edit_actions_remove_url_form(struct client_state *csp, err = map(exports, "f", 1, file->identifier, 1); if (!err) err = map(exports, "v", 1, file->version_str, 1); - if (!err) err = map(exports, "s", 1, url_encode(lookup(parameters, "s")), 0); + if (!err) err = map(exports, "p", 1, url_encode(lookup(parameters, "p")), 0); if (!err) err = map(exports, "u", 1, html_encode(cur_line->unprocessed), 0); + if (!err) err = map(exports, "jumptarget", 1, section_target(section_start_line_number), 0); edit_free_file(file); @@ -885,7 +998,7 @@ jb_err edit_write_file(struct editable_file * file) { /* Must quote '#' characters */ int numhash = 0; - int len; + size_t len; char * src; char * dest; char * str; @@ -901,7 +1014,7 @@ jb_err edit_write_file(struct editable_file * file) /* Allocate new memory for string */ len = strlen(cur_line->unprocessed); - if (NULL == (str = malloc((size_t) len + 1 + numhash))) + if (NULL == (str = malloc(len + 1 + (size_t)numhash))) { /* Uh oh, just trashed file! */ fclose(fp); @@ -1183,7 +1296,7 @@ static jb_err split_line_on_equals(const char * line, char ** pname, char ** pva name_end--; } - name_len = name_end - line + 1; /* Length excluding \0 */ + name_len = (size_t)(name_end - line) + 1; /* Length excluding \0 */ if (NULL == (*pname = (char *) malloc(name_len + 1))) { return JB_ERR_MEMORY; @@ -1879,7 +1992,7 @@ static jb_err get_file_name_param(struct client_state *csp, char *name; char *fullpath; char ch; - int len; + size_t len; assert(csp); assert(parameters); @@ -2136,7 +2249,7 @@ static jb_err map_radio(struct map * exports, } } - *p = value; + *p = (char)value; return map(exports, buf, 0, "checked", 1); } @@ -2330,40 +2443,6 @@ jb_err cgi_error_file_read_only(struct client_state *csp, } -/********************************************************************* - * - * Function : cgi_error_disabled - * - * Description : CGI function that is called if the actions editor - * is called although it's disabled in config - * - * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : rsp = http_response data structure for output - * - * CGI Parameters : none - * - * Returns : JB_ERR_OK on success - * JB_ERR_MEMORY on out-of-memory error. - * - *********************************************************************/ -jb_err cgi_error_disabled(struct client_state *csp, - struct http_response *rsp) -{ - struct map *exports; - - assert(csp); - assert(rsp); - - if (NULL == (exports = default_exports(csp, NULL))) - { - return JB_ERR_MEMORY; - } - - return template_fill_for_cgi(csp, "cgi-error-disabled", exports, rsp); -} - - /********************************************************************* * * Function : cgi_edit_actions @@ -2393,20 +2472,9 @@ jb_err cgi_edit_actions(struct client_state *csp, } /* FIXME: Incomplete */ - rsp->status = strdup("302 Local Redirect from Privoxy"); - if (rsp->status == NULL) - { - return JB_ERR_MEMORY; - } - if (enlist_unique_header(rsp->headers, "Location", - CGI_PREFIX "edit-actions-list?f=default")) - { - free(rsp->status); - rsp->status = NULL; - return JB_ERR_MEMORY; - } - return JB_ERR_OK; + return cgi_redirect(rsp, CGI_PREFIX "edit-actions-list?f=default"); + } @@ -2462,7 +2530,6 @@ jb_err cgi_edit_actions_list(struct client_state *csp, if (NULL == (exports = default_exports(csp, NULL))) { - edit_free_file(file); return JB_ERR_MEMORY; } @@ -2526,7 +2593,7 @@ jb_err cgi_edit_actions_list(struct client_state *csp, } buttons = strdup(""); - for (i = 0; i < MAX_ACTION_FILES; i++) + for (i = 0; i < MAX_AF_FILES; i++) { if (((fl = csp->actions_list[i]) != NULL) && ((b = fl->f) != NULL)) { @@ -2824,12 +2891,13 @@ jb_err cgi_edit_actions_list(struct client_state *csp, /* Could also do section-specific exports here, but it wouldn't be as fast */ + snprintf(buf, 150, "%d", line_number); + if (!err) err = map(section_exports, "s-next", 1, buf, 1); + if ( (cur_line != NULL) && (cur_line->type == FILE_LINE_ACTION)) { /* Not last section */ - snprintf(buf, 150, "%d", line_number); - if (!err) err = map(section_exports, "s-next", 1, buf, 1); if (!err) err = map_block_keep(section_exports, "s-next-exists"); } else @@ -2923,8 +2991,8 @@ jb_err cgi_edit_actions_for_url(struct client_state *csp, struct file_line * cur_line; unsigned line_number; jb_err err; - struct file_list *filter_file; struct re_filterfile_spec *filter_group; + int i, have_filters = 0; if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS)) { @@ -2973,10 +3041,44 @@ jb_err cgi_edit_actions_for_url(struct client_state *csp, if (!err) err = actions_to_radio(exports, cur_line->data.action); - filter_file = csp->rlist; - filter_group = ((filter_file != NULL) ? filter_file->f : NULL); + /* + * XXX: Some browsers (at least IE6 and IE7) have an artifical URL + * length limitation and ignore clicks on the Submit buttons if + * the resulting GET URL would be longer than their limit. + * + * In Privoxy 3.0.5 beta the standard edit-actions-for-url template + * reached this limit and action editing stopped working in these + * browsers (BR #1570678). + * + * The config option split-large-forms works around this browser + * bug (HTTP has no URL lenght limitation) by deviding the action + * list form into multiple smaller ones. It means the URLs are shorter + * and work in broken browsers as well, but the user can no longer change + * all actions with one submit. + * + * A better solution would be to switch to POST requests, + * but this will do for now. + */ + if(!err && (csp->config->feature_flags & RUNTIME_FEATURE_SPLIT_LARGE_FORMS)) + { + /* Generate multiple smaller form by killing the big one. */ + err = map_block_killer(exports, "one-form-only"); + } + else + { + /* Default: Generate one large form by killing the smaller ones. */ + err = map_block_killer(exports, "multiple-forms"); + } - if (!err) err = map_conditional(exports, "any-filters-defined", (filter_group != NULL)); + for (i = 0; i < MAX_AF_FILES; i++) + { + if ((csp->rlist[i] != NULL) && (csp->rlist[i]->f != NULL)) + { + if (!err) err = map_conditional(exports, "any-filters-defined", 1); + have_filters = 1; + break; + } + } if (err) { @@ -2985,15 +3087,13 @@ jb_err cgi_edit_actions_for_url(struct client_state *csp, return err; } - if (filter_group == NULL) - { + if (0 == have_filters) err = map(exports, "filter-params", 1, "", 1); - } else { /* We have some entries in the filter list */ char * result; - int index = 0; + int filter_identifier = 0; char * filter_template; err = template_load(csp, &filter_template, "edit-actions-for-url-filter", 0); @@ -3012,69 +3112,75 @@ jb_err cgi_edit_actions_for_url(struct client_state *csp, result = strdup(""); - for (;(!err) && (filter_group != NULL); filter_group = filter_group->next) + for (i = 0; i < MAX_AF_FILES; i++) { - char current_mode = 'x'; - struct list_entry *filter_name; - char * this_line; - struct map *line_exports; - char number[20]; - - filter_name = cur_line->data.action->multi_add[ACTION_MULTI_FILTER]->first; - while ((filter_name != NULL) - && (0 != strcmp(filter_group->name, filter_name->str))) + if ((csp->rlist[i] != NULL) && (csp->rlist[i]->f != NULL)) { - filter_name = filter_name->next; - } - - if (filter_name != NULL) - { - current_mode = 'y'; - } - else - { - filter_name = cur_line->data.action->multi_remove[ACTION_MULTI_FILTER]->first; - while ((filter_name != NULL) - && (0 != strcmp(filter_group->name, filter_name->str))) - { - filter_name = filter_name->next; - } - if (filter_name != NULL) + filter_group = csp->rlist[i]->f; + for (;(!err) && (filter_group != NULL); filter_group = filter_group->next) { - current_mode = 'n'; - } - } + char current_mode = 'x'; + struct list_entry *filter_name; + char * this_line; + struct map *line_exports; + char number[20]; + + filter_name = cur_line->data.action->multi_add[ACTION_MULTI_FILTER]->first; + while ((filter_name != NULL) + && (0 != strcmp(filter_group->name, filter_name->str))) + { + filter_name = filter_name->next; + } - /* Generate a unique serial number */ - snprintf(number, sizeof(number), "%x", index++); - number[sizeof(number) - 1] = '\0'; + if (filter_name != NULL) + { + current_mode = 'y'; + } + else + { + filter_name = cur_line->data.action->multi_remove[ACTION_MULTI_FILTER]->first; + while ((filter_name != NULL) + && (0 != strcmp(filter_group->name, filter_name->str))) + { + filter_name = filter_name->next; + } + if (filter_name != NULL) + { + current_mode = 'n'; + } + } - line_exports = new_map(); - if (line_exports == NULL) - { - err = JB_ERR_MEMORY; - freez(result); - } - else - { - if (!err) err = map(line_exports, "index", 1, number, 1); - 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); + /* Generate a unique serial number */ + snprintf(number, sizeof(number), "%x", filter_identifier++); + number[sizeof(number) - 1] = '\0'; - this_line = NULL; - if (!err) - { - this_line = strdup(filter_template); - if (this_line == NULL) err = JB_ERR_MEMORY; - } - if (!err) err = template_fill(&this_line, line_exports); - string_join(&result, this_line); + line_exports = new_map(); + if (line_exports == NULL) + { + err = JB_ERR_MEMORY; + freez(result); + } + else + { + if (!err) err = map(line_exports, "index", 1, number, 1); + 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); - free_map(line_exports); + this_line = NULL; + if (!err) + { + this_line = strdup(filter_template); + if (this_line == NULL) err = JB_ERR_MEMORY; + } + if (!err) err = template_fill(&this_line, line_exports); + string_join(&result, this_line); + + free_map(line_exports); + } + } } } - freez(filter_template); if (!err) @@ -3132,9 +3238,9 @@ jb_err cgi_edit_actions_submit(struct client_state *csp, struct editable_file * file; struct file_line * cur_line; unsigned line_number; - char * target; + char target[1024]; jb_err err; - int index; + int filter_identifier; const char * action_set_name; char ch; struct file_list * fl; @@ -3178,9 +3284,9 @@ jb_err cgi_edit_actions_submit(struct client_state *csp, get_string_param(parameters, "p", &action_set_name); if (action_set_name != NULL) { - for (index = 0; index < MAX_ACTION_FILES; index++) + for (filter_identifier = 0; filter_identifier < MAX_AF_FILES; filter_identifier++) { - if (((fl = csp->actions_list[index]) != NULL) && ((b = fl->f) != NULL)) + if (((fl = csp->actions_list[filter_identifier]) != NULL) && ((b = fl->f) != NULL)) { for (b = b->next; NULL != b; b = b->next) { @@ -3221,7 +3327,7 @@ jb_err cgi_edit_actions_submit(struct client_state *csp, cur_line->data.action->multi_remove_all[ACTION_MULTI_FILTER] = 0; } - for (index = 0; !err; index++) + for (filter_identifier = 0; !err; filter_identifier++) { char key_value[30]; char key_name[30]; @@ -3229,9 +3335,9 @@ jb_err cgi_edit_actions_submit(struct client_state *csp, char value; /* Generate the keys */ - snprintf(key_value, sizeof(key_value), "filter_r%x", index); + snprintf(key_value, sizeof(key_value), "filter_r%x", filter_identifier); key_value[sizeof(key_value) - 1] = '\0'; - snprintf(key_name, sizeof(key_name), "filter_n%x", index); + snprintf(key_name, sizeof(key_name), "filter_n%x", filter_identifier); key_name[sizeof(key_name) - 1] = '\0'; err = get_string_param(parameters, key_name, &name); @@ -3320,27 +3426,12 @@ jb_err cgi_edit_actions_submit(struct client_state *csp, return err; } - target = strdup(CGI_PREFIX "edit-actions-list?f="); - string_append(&target, file->identifier); + snprintf(target, 1024, CGI_PREFIX "edit-actions-list?foo=%lu&f=%s#l%d", + (long) time(NULL), file->identifier, sectionid); edit_free_file(file); - if (target == NULL) - { - /* Out of memory */ - return JB_ERR_MEMORY; - } - - rsp->status = strdup("302 Local Redirect from Privoxy"); - if (rsp->status == NULL) - { - free(target); - return JB_ERR_MEMORY; - } - err = enlist_unique_header(rsp->headers, "Location", target); - free(target); - - return err; + return cgi_redirect(rsp, target); } @@ -3378,9 +3469,14 @@ jb_err cgi_edit_actions_url(struct client_state *csp, struct editable_file * file; struct file_line * cur_line; unsigned line_number; - char * target; + unsigned section_start_line_number = 0; + char target[1024]; jb_err err; + assert(csp); + assert(rsp); + assert(parameters); + if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS)) { return cgi_error_disabled(csp, rsp); @@ -3415,6 +3511,10 @@ jb_err cgi_edit_actions_url(struct client_state *csp, while ((cur_line != NULL) && (line_number < patternid)) { + if (cur_line->type == FILE_LINE_ACTION) + { + section_start_line_number = line_number; + } cur_line = cur_line->next; line_number++; } @@ -3447,27 +3547,12 @@ jb_err cgi_edit_actions_url(struct client_state *csp, return err; } - target = strdup(CGI_PREFIX "edit-actions-list?f="); - string_append(&target, file->identifier); + snprintf(target, 1024, CGI_PREFIX "edit-actions-list?foo=%lu&f=%s#l%d", + (long) time(NULL), file->identifier, section_start_line_number); edit_free_file(file); - if (target == NULL) - { - /* Out of memory */ - return JB_ERR_MEMORY; - } - - rsp->status = strdup("302 Local Redirect from Privoxy"); - if (rsp->status == NULL) - { - free(target); - return JB_ERR_MEMORY; - } - err = enlist_unique_header(rsp->headers, "Location", target); - free(target); - - return err; + return cgi_redirect(rsp, target); } @@ -3505,7 +3590,7 @@ jb_err cgi_edit_actions_add_url(struct client_state *csp, struct editable_file * file; struct file_line * cur_line; unsigned line_number; - char * target; + char target[1024]; jb_err err; if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS)) @@ -3591,27 +3676,12 @@ jb_err cgi_edit_actions_add_url(struct client_state *csp, return err; } - target = strdup(CGI_PREFIX "edit-actions-list?f="); - string_append(&target, file->identifier); + snprintf(target, 1024, CGI_PREFIX "edit-actions-list?foo=%lu&f=%s#l%d", + (long) time(NULL), file->identifier, sectionid); edit_free_file(file); - if (target == NULL) - { - /* Out of memory */ - return JB_ERR_MEMORY; - } - - rsp->status = strdup("302 Local Redirect from Privoxy"); - if (rsp->status == NULL) - { - free(target); - return JB_ERR_MEMORY; - } - err = enlist_unique_header(rsp->headers, "Location", target); - free(target); - - return err; + return cgi_redirect(rsp, target); } @@ -3647,7 +3717,8 @@ jb_err cgi_edit_actions_remove_url(struct client_state *csp, struct file_line * cur_line; struct file_line * prev_line; unsigned line_number; - char * target; + unsigned section_start_line_number = 0; + char target[1024]; jb_err err; if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS)) @@ -3674,6 +3745,10 @@ jb_err cgi_edit_actions_remove_url(struct client_state *csp, while ((cur_line != NULL) && (line_number < patternid)) { + if (cur_line->type == FILE_LINE_ACTION) + { + section_start_line_number = line_number; + } prev_line = cur_line; cur_line = cur_line->next; line_number++; @@ -3712,27 +3787,12 @@ jb_err cgi_edit_actions_remove_url(struct client_state *csp, return err; } - target = strdup(CGI_PREFIX "edit-actions-list?f="); - string_append(&target, file->identifier); + snprintf(target, 1024, CGI_PREFIX "edit-actions-list?foo=%lu&f=%s#l%d", + (long) time(NULL), file->identifier, section_start_line_number); edit_free_file(file); - if (target == NULL) - { - /* Out of memory */ - return JB_ERR_MEMORY; - } - - rsp->status = strdup("302 Local Redirect from Privoxy"); - if (rsp->status == NULL) - { - free(target); - return JB_ERR_MEMORY; - } - err = enlist_unique_header(rsp->headers, "Location", target); - free(target); - - return err; + return cgi_redirect(rsp, target); } @@ -3769,7 +3829,7 @@ jb_err cgi_edit_actions_section_remove(struct client_state *csp, struct file_line * cur_line; struct file_line * prev_line; unsigned line_number; - char * target; + char target[1024]; jb_err err; if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS)) @@ -3849,27 +3909,12 @@ jb_err cgi_edit_actions_section_remove(struct client_state *csp, return err; } - target = strdup(CGI_PREFIX "edit-actions-list?f="); - string_append(&target, file->identifier); + snprintf(target, 1024, CGI_PREFIX "edit-actions-list?foo=%lu&f=%s", + (long) time(NULL), file->identifier); edit_free_file(file); - if (target == NULL) - { - /* Out of memory */ - return JB_ERR_MEMORY; - } - - rsp->status = strdup("302 Local Redirect from Privoxy"); - if (rsp->status == NULL) - { - free(target); - return JB_ERR_MEMORY; - } - err = enlist_unique_header(rsp->headers, "Location", target); - free(target); - - return err; + return cgi_redirect(rsp, target); } @@ -3907,7 +3952,7 @@ jb_err cgi_edit_actions_section_add(struct client_state *csp, struct editable_file * file; struct file_line * cur_line; unsigned line_number; - char * target; + char target[1024]; jb_err err; if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS)) @@ -3931,10 +3976,10 @@ jb_err cgi_edit_actions_section_add(struct client_state *csp, line_number = 1; cur_line = file->lines; - if (sectionid < 1U) + if (sectionid <= 1U) { /* Add to start of file */ - if (cur_line != NULL) + if (cur_line != NULL && cur_line->type != FILE_LINE_ACTION) { /* There's something in the file, find the line before the first * action. @@ -3946,6 +3991,11 @@ jb_err cgi_edit_actions_section_add(struct client_state *csp, line_number++; } } + else + { + /* File starts with action line, so insert at top */ + cur_line = NULL; + } } else { @@ -4028,27 +4078,12 @@ jb_err cgi_edit_actions_section_add(struct client_state *csp, return err; } - target = strdup(CGI_PREFIX "edit-actions-list?f="); - string_append(&target, file->identifier); + snprintf(target, 1024, CGI_PREFIX "edit-actions-list?foo=%lu&f=%s", + (long) time(NULL), file->identifier); edit_free_file(file); - if (target == NULL) - { - /* Out of memory */ - return JB_ERR_MEMORY; - } - - rsp->status = strdup("302 Local Redirect from Privoxy"); - if (rsp->status == NULL) - { - free(target); - return JB_ERR_MEMORY; - } - err = enlist_unique_header(rsp->headers, "Location", target); - free(target); - - return err; + return cgi_redirect(rsp, target); } @@ -4097,7 +4132,7 @@ jb_err cgi_edit_actions_section_swap(struct client_state *csp, struct file_line * line_end_section2; struct file_line * line_after_section2; unsigned line_number; - char * target; + char target[1024]; jb_err err; if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS)) @@ -4232,30 +4267,15 @@ jb_err cgi_edit_actions_section_swap(struct client_state *csp, } } /* END if (section1 != section2) */ - target = strdup(CGI_PREFIX "edit-actions-list?f="); - string_append(&target, file->identifier); + snprintf(target, 1024, CGI_PREFIX "edit-actions-list?foo=%lu&f=%s", + (long) time(NULL), file->identifier); edit_free_file(file); - if (target == NULL) - { - /* Out of memory */ - return JB_ERR_MEMORY; - } - - rsp->status = strdup("302 Local Redirect from Privoxy"); - if (rsp->status == NULL) - { - free(target); - return JB_ERR_MEMORY; - } - err = enlist_unique_header(rsp->headers, "Location", target); - free(target); - - return err; + return cgi_redirect(rsp, target); } - +#ifdef FEATURE_TOGGLE /********************************************************************* * * Function : cgi_toggle @@ -4299,17 +4319,17 @@ jb_err cgi_toggle(struct client_state *csp, if (mode == 'E') { /* Enable */ - g_bToggleIJB = 1; + global_toggle_state = 1; } else if (mode == 'D') { /* Disable */ - g_bToggleIJB = 0; + global_toggle_state = 0; } else if (mode == 'T') { /* Toggle */ - g_bToggleIJB = !g_bToggleIJB; + global_toggle_state = !global_toggle_state; } if (NULL == (exports = default_exports(csp, "toggle"))) @@ -4323,7 +4343,7 @@ jb_err cgi_toggle(struct client_state *csp, return template_fill_for_cgi(csp, template_name, exports, rsp); } - +#endif /* def FEATURE_TOGGLE */ /********************************************************************* * @@ -4512,7 +4532,6 @@ static jb_err actions_to_radio(struct map * exports, static jb_err actions_from_radio(const struct map * parameters, struct action_spec *action) { - static int first_time = 1; const char * param; char * param_dup; char ch; @@ -4526,16 +4545,22 @@ static jb_err actions_from_radio(const struct map * parameters, * but in this case we're safe and don't need semaphores. * Be careful if you modify this function. * - Jon + * The js_name_arr's are never free()d, but this is no + * problem, since they will only be created once and + * used by all threads thereafter. -oes */ #define JAVASCRIPTIFY(dest_var, string) \ { \ - static char js_name_arr[] = string; \ + static int first_time = 1; \ + static char *js_name_arr; \ if (first_time) \ { \ + js_name_arr = strdup(string); \ javascriptify(js_name_arr); \ } \ dest_var = js_name_arr; \ + first_time = 0; \ } \ #define DEFINE_ACTION_BOOL(name, bit) \ @@ -4631,8 +4656,6 @@ static jb_err actions_from_radio(const struct map * parameters, #undef DEFINE_ACTION_ALIAS #undef JAVASCRIPTIFY - first_time = 0; - return err; }