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
This commit is contained in:
parent
32924ce7e8
commit
dc1d2b4ed5
3 changed files with 67 additions and 40 deletions
|
@ -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,
|
undo_set_change_state_func(undostruct, &sieve_editor_undo_state_changed,
|
||||||
page);
|
page);
|
||||||
|
|
||||||
gtk_widget_show_all(window);
|
|
||||||
|
|
||||||
page->window = window;
|
page->window = window;
|
||||||
page->ui_manager = ui_manager;
|
page->ui_manager = ui_manager;
|
||||||
page->text = text;
|
page->text = text;
|
||||||
|
@ -661,6 +659,11 @@ void sieve_editor_present(SieveEditorPage *page)
|
||||||
gtk_window_present(GTK_WINDOW(page->window));
|
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,
|
static void sieve_editor_set_modified(SieveEditorPage *page,
|
||||||
gboolean modified)
|
gboolean modified)
|
||||||
{
|
{
|
||||||
|
@ -680,3 +683,49 @@ static void sieve_editor_set_modified(SieveEditorPage *page,
|
||||||
sieve_editor_set_status_icon(page, NULL);
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -38,12 +38,19 @@ struct SieveEditorPage
|
||||||
gboolean first_line;
|
gboolean first_line;
|
||||||
gboolean modified;
|
gboolean modified;
|
||||||
gboolean closing;
|
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_new(SieveSession *session, gchar *script_name);
|
||||||
SieveEditorPage *sieve_editor_get(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_append_text(SieveEditorPage *page, gchar *text, gint len);
|
||||||
void sieve_editor_close(SieveEditorPage *page);
|
void sieve_editor_close(SieveEditorPage *page);
|
||||||
|
void sieve_editor_show(SieveEditorPage *page);
|
||||||
void sieve_editor_present(SieveEditorPage *page);
|
void sieve_editor_present(SieveEditorPage *page);
|
||||||
|
|
||||||
#endif /* SIEVE_EDITOR_H */
|
#endif /* SIEVE_EDITOR_H */
|
||||||
|
|
|
@ -59,13 +59,6 @@ typedef struct {
|
||||||
gchar *filter_name;
|
gchar *filter_name;
|
||||||
} CommandDataName;
|
} CommandDataName;
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
SieveManagerPage *page;
|
|
||||||
gchar *filter_name;
|
|
||||||
SieveEditorPage *editor_page;
|
|
||||||
gboolean first_line;
|
|
||||||
} CommandDataGetScript;
|
|
||||||
|
|
||||||
static void account_changed(GtkWidget *widget, SieveManagerPage *page);
|
static void account_changed(GtkWidget *widget, SieveManagerPage *page);
|
||||||
void sieve_manager_close(GtkWidget *widget, SieveManagerPage *page);
|
void sieve_manager_close(GtkWidget *widget, SieveManagerPage *page);
|
||||||
static void filter_set_active(SieveManagerPage *page, gchar *filter_name);
|
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])
|
if (!filter_name || !filter_name[0])
|
||||||
return;
|
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_add_script(session, filter_name
|
||||||
(sieve_session_data_cb_fn)filter_added, (gpointer)page);
|
(sieve_session_data_cb_fn)filter_added, (gpointer)page);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
static void filter_got_data(SieveSession *session, gboolean abort,
|
static void filter_got_load_error(SieveSession *session, gpointer data)
|
||||||
gchar *contents, CommandDataGetScript *cmd_data)
|
|
||||||
{
|
{
|
||||||
SieveManagerPage *page = cmd_data->page;
|
SieveManagerPage *page = data;
|
||||||
SieveEditorPage *editor;
|
|
||||||
|
|
||||||
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);
|
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void filter_edit(GtkWidget *widget, SieveManagerPage *page)
|
static void filter_edit(GtkWidget *widget, SieveManagerPage *page)
|
||||||
{
|
{
|
||||||
SieveEditorPage *editor;
|
SieveEditorPage *editor;
|
||||||
CommandDataGetScript *cmd_data;
|
|
||||||
SieveSession *session = page->active_session;
|
SieveSession *session = page->active_session;
|
||||||
|
|
||||||
if (!session)
|
if (!session)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
gchar *filter_name = filters_list_get_selected_filter(page->filters_list);
|
gchar *filter_name = filters_list_get_selected_filter(page->filters_list);
|
||||||
if (!filter_name)
|
if (!filter_name)
|
||||||
return;
|
return;
|
||||||
|
@ -205,13 +180,9 @@ static void filter_edit(GtkWidget *widget, SieveManagerPage *page)
|
||||||
if (editor) {
|
if (editor) {
|
||||||
sieve_editor_present(editor);
|
sieve_editor_present(editor);
|
||||||
} else {
|
} else {
|
||||||
cmd_data = g_new0(CommandDataGetScript, 1);
|
editor = sieve_editor_new(session, filter_name);
|
||||||
cmd_data->first_line = TRUE;
|
sieve_editor_load(editor,
|
||||||
cmd_data->filter_name = filter_name;
|
(sieve_session_cb_fn)filter_got_load_error, page);
|
||||||
cmd_data->page = page;
|
|
||||||
|
|
||||||
sieve_session_get_script(session, filter_name,
|
|
||||||
(sieve_session_data_cb_fn)filter_got_data, cmd_data);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue