talons

Fork of Claws Mail https://www.claws-mail
Log | Files | Refs | README | LICENSE

commit dc1d2b4ed5c5c7582275a5b4addbd894ef8a856c
parent 32924ce7e82afbe83ffa9087fa56694825c6d0ef
Author: Charles Lehner <cel@celehner.com>
Date:   Thu,  9 Jul 2015 03:24:02 -0400

managesieve: allow script loading to be interrupted

Prevent use after free when an editor window is closed while loading

Uses string "Loading..." which is already translated

Diffstat:
Msrc/plugins/managesieve/sieve_editor.c | 53+++++++++++++++++++++++++++++++++++++++++++++++++++--
Msrc/plugins/managesieve/sieve_editor.h | 7+++++++
Msrc/plugins/managesieve/sieve_manager.c | 47+++++++++--------------------------------------
3 files changed, 67 insertions(+), 40 deletions(-)

diff --git a/src/plugins/managesieve/sieve_editor.c b/src/plugins/managesieve/sieve_editor.c @@ -625,8 +625,6 @@ MENUITEM_ADDUI_MANAGER(ui_manager, "/Menu/Filter", "Revert", "Filter/Revert", GT undo_set_change_state_func(undostruct, &sieve_editor_undo_state_changed, page); - gtk_widget_show_all(window); - page->window = window; page->ui_manager = ui_manager; page->text = text; @@ -661,6 +659,11 @@ void sieve_editor_present(SieveEditorPage *page) gtk_window_present(GTK_WINDOW(page->window)); } +void sieve_editor_show(SieveEditorPage *page) +{ + gtk_widget_show_all(GTK_WIDGET(page->window)); +} + static void sieve_editor_set_modified(SieveEditorPage *page, gboolean modified) { @@ -680,3 +683,49 @@ static void sieve_editor_set_modified(SieveEditorPage *page, sieve_editor_set_status_icon(page, NULL); } } + +static void got_data_loading(SieveSession *session, gboolean aborted, + gchar *contents, SieveEditorPage *page) +{ + if (aborted) + return; + if (contents == NULL) { + /* end of data */ + sieve_editor_set_status(page, ""); + return; + } + if (contents == (void *)-1) { + /* error */ + if (page->first_line) { + /* no data. show error in manager window */ + if (page->on_load_error) + page->on_load_error(session, page->on_load_error_data); + } else { + /* partial failure. show error in editor window */ + sieve_editor_set_status(page, _("Unable to get script contents")); + sieve_editor_set_status_icon(page, GTK_STOCK_DIALOG_ERROR); + } + return; + } + + if (page->first_line) { + page->first_line = FALSE; + sieve_editor_show(page); + } else { + sieve_editor_append_text(page, "\n", 1); + } + sieve_editor_append_text(page, contents, strlen(contents)); +} + +/* load the script for this editor */ +void sieve_editor_load(SieveEditorPage *page, + sieve_session_cb_fn on_load_error, gpointer load_error_data) +{ + page->first_line = TRUE; + page->on_load_error = on_load_error; + page->on_load_error_data = load_error_data; + sieve_editor_set_status(page, _("Loading...")); + sieve_editor_set_status_icon(page, NULL); + sieve_session_get_script(page->session, page->script_name, + (sieve_session_data_cb_fn)got_data_loading, page); +} diff --git a/src/plugins/managesieve/sieve_editor.h b/src/plugins/managesieve/sieve_editor.h @@ -38,12 +38,19 @@ struct SieveEditorPage gboolean first_line; gboolean modified; gboolean closing; + + /* callback for failure to load the script */ + sieve_session_cb_fn on_load_error; + gpointer on_load_error_data; }; SieveEditorPage *sieve_editor_new(SieveSession *session, gchar *script_name); SieveEditorPage *sieve_editor_get(SieveSession *session, gchar *script_name); +void sieve_editor_load(SieveEditorPage *page, + sieve_session_cb_fn on_load_error, gpointer load_error_data); void sieve_editor_append_text(SieveEditorPage *page, gchar *text, gint len); void sieve_editor_close(SieveEditorPage *page); +void sieve_editor_show(SieveEditorPage *page); void sieve_editor_present(SieveEditorPage *page); #endif /* SIEVE_EDITOR_H */ diff --git a/src/plugins/managesieve/sieve_manager.c b/src/plugins/managesieve/sieve_manager.c @@ -59,13 +59,6 @@ typedef struct { gchar *filter_name; } CommandDataName; -typedef struct { - SieveManagerPage *page; - gchar *filter_name; - SieveEditorPage *editor_page; - gboolean first_line; -} CommandDataGetScript; - static void account_changed(GtkWidget *widget, SieveManagerPage *page); void sieve_manager_close(GtkWidget *widget, SieveManagerPage *page); static void filter_set_active(SieveManagerPage *page, gchar *filter_name); @@ -157,46 +150,28 @@ static void filter_add(GtkWidget *widget, SieveManagerPage *page) if (!filter_name || !filter_name[0]) return; - sieve_editor_new(session, filter_name); + sieve_editor_show(sieve_editor_new(session, filter_name)); /* sieve_session_add_script(session, filter_name (sieve_session_data_cb_fn)filter_added, (gpointer)page); */ } -static void filter_got_data(SieveSession *session, gboolean abort, - gchar *contents, CommandDataGetScript *cmd_data) +static void filter_got_load_error(SieveSession *session, gpointer data) { - SieveManagerPage *page = cmd_data->page; - SieveEditorPage *editor; + SieveManagerPage *page = data; - if (abort || !contents) { - g_free(cmd_data->filter_name); - g_free(cmd_data); - return; - } else if (contents == (void *)-1) { - got_session_error(session, _("Unable to get script contents"), page); - return; - } - - if (cmd_data->first_line) { - cmd_data->first_line = FALSE; - editor = sieve_editor_new(session, cmd_data->filter_name); - cmd_data->editor_page = editor; - } else { - editor = cmd_data->editor_page; - sieve_editor_append_text(editor, "\n", 1); - } - sieve_editor_append_text(editor, contents, strlen(contents)); + got_session_error(session, _("Unable to get script contents"), page); } static void filter_edit(GtkWidget *widget, SieveManagerPage *page) { SieveEditorPage *editor; - CommandDataGetScript *cmd_data; SieveSession *session = page->active_session; + if (!session) return; + gchar *filter_name = filters_list_get_selected_filter(page->filters_list); if (!filter_name) return; @@ -205,13 +180,9 @@ static void filter_edit(GtkWidget *widget, SieveManagerPage *page) if (editor) { sieve_editor_present(editor); } else { - cmd_data = g_new0(CommandDataGetScript, 1); - cmd_data->first_line = TRUE; - cmd_data->filter_name = filter_name; - cmd_data->page = page; - - sieve_session_get_script(session, filter_name, - (sieve_session_data_cb_fn)filter_got_data, cmd_data); + editor = sieve_editor_new(session, filter_name); + sieve_editor_load(editor, + (sieve_session_cb_fn)filter_got_load_error, page); } }