From eb088099b072573c67bc1a1be5e0bebea63606f0 Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Tue, 12 Oct 2004 03:13:17 +0000 Subject: [PATCH] Check the values of the protocol preferences before fetching them; if any are not valid, pop up an alert box and don't dismiss the preferences dialog. svn path=/trunk/; revision=12269 --- epan/prefs.c | 42 +++++++++---------- epan/prefs.h | 6 +-- gtk/prefs_dlg.c | 106 ++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 115 insertions(+), 39 deletions(-) diff --git a/epan/prefs.c b/epan/prefs.c index a2b77bdace..1def43c844 100644 --- a/epan/prefs.c +++ b/epan/prefs.c @@ -316,43 +316,39 @@ find_module(const char *name) return (module_t *) list_entry->data; } -typedef struct { - module_cb callback; - gpointer user_data; -} module_cb_arg_t; - -static void -do_module_callback(gpointer data, gpointer user_data) -{ - module_t *module = data; - module_cb_arg_t *arg = user_data; - - if (!module->obsolete) - (*arg->callback)(module, arg->user_data); -} - /* * Call a callback function, with a specified argument, for each module * in a list of modules. If the list is NULL, searches the top-level - * list in the display tree of modules. + * list in the display tree of modules. If any callback returns a + * non-zero value, we stop and return that value, otherwise we + * return 0. * * Ignores "obsolete" modules; their sole purpose is to allow old * preferences for dissectors that no longer have preferences to be * silently ignored in preference files. Does not ignore subtrees, * as this can be used when walking the display tree of modules. */ -void +guint prefs_module_list_foreach(GList *module_list, module_cb callback, gpointer user_data) { - module_cb_arg_t arg; + GList *elem; + module_t *module; + guint ret; if (module_list == NULL) module_list = top_level_modules; - arg.callback = callback; - arg.user_data = user_data; - g_list_foreach(module_list, do_module_callback, &arg); + for (elem = g_list_first(module_list); elem != NULL; + elem = g_list_next(elem)) { + module = elem->data; + if (!module->obsolete) { + ret = (*callback)(module, user_data); + if (ret != 0) + return ret; + } + } + return 0; } /* @@ -363,10 +359,10 @@ prefs_module_list_foreach(GList *module_list, module_cb callback, * preferences for dissectors that no longer have preferences to be * silently ignored in preference files. */ -void +guint prefs_modules_foreach(module_cb callback, gpointer user_data) { - prefs_module_list_foreach(modules, callback, user_data); + return prefs_module_list_foreach(modules, callback, user_data); } static void diff --git a/epan/prefs.h b/epan/prefs.h index 8f2c274fc1..5a6f589a4b 100644 --- a/epan/prefs.h +++ b/epan/prefs.h @@ -196,7 +196,7 @@ extern module_t *prefs_register_protocol_obsolete(int id); /* * Callback function for module list scanners. */ -typedef void (*module_cb)(module_t *module, gpointer user_data); +typedef guint (*module_cb)(module_t *module, gpointer user_data); /* * Call a callback function, with a specified argument, for each module @@ -208,7 +208,7 @@ typedef void (*module_cb)(module_t *module, gpointer user_data); * silently ignored in preference files. Does not ignore subtrees, * as this can be used when walking the display tree of modules. */ -extern void prefs_module_list_foreach(GList *module_list, module_cb callback, +extern guint prefs_module_list_foreach(GList *module_list, module_cb callback, gpointer user_data); /* @@ -219,7 +219,7 @@ extern void prefs_module_list_foreach(GList *module_list, module_cb callback, * preferences for dissectors that no longer have preferences to be * silently ignored in preference files. */ -extern void prefs_modules_foreach(module_cb callback, gpointer user_data); +extern guint prefs_modules_foreach(module_cb callback, gpointer user_data); /* * Call the "apply" callback function for each module if any of its diff --git a/gtk/prefs_dlg.c b/gtk/prefs_dlg.c index d52e3a8ff2..cf329a0524 100644 --- a/gtk/prefs_dlg.c +++ b/gtk/prefs_dlg.c @@ -213,7 +213,7 @@ pref_show(pref_t *pref, gpointer user_data) #define MAX_TREE_NODE_NAME_LEN 64 /* show prefs page for each registered module (protocol) */ -static void +static guint module_prefs_show(module_t *module, gpointer user_data) { struct ct_struct *cts = user_data; @@ -243,7 +243,7 @@ module_prefs_show(module_t *module, gpointer user_data) * nothing under it that will be displayed, don't put it into * the window. */ - return; + return 0; } } @@ -334,6 +334,8 @@ module_prefs_show(module_t *module, gpointer user_data) /* Show 'em what we got */ gtk_widget_show_all(main_vb); } + + return 0; } @@ -852,6 +854,53 @@ create_preference_entry(GtkWidget *main_tb, int table_position, return entry; } +static guint +pref_check(pref_t *pref, gpointer user_data) +{ + const char *str_val; + char *p; + guint uval; + pref_t **badpref = user_data; + + /* Fetch the value of the preference, and check whether it's valid. */ + switch (pref->type) { + + case PREF_UINT: + str_val = gtk_entry_get_text(GTK_ENTRY(pref->control)); + uval = strtoul(str_val, &p, pref->info.base); + if (p == str_val || *p != '\0') { + *badpref = pref; + return PREFS_SET_SYNTAX_ERR; /* number was bad */ + } + break; + + case PREF_BOOL: + /* Value can't be bad. */ + break; + + case PREF_ENUM: + /* Value can't be bad. */ + break; + + case PREF_STRING: + /* Value can't be bad. */ + break; + + case PREF_OBSOLETE: + g_assert_not_reached(); + break; + } + return 0; +} + +static guint +module_prefs_check(module_t *module, gpointer user_data) +{ + /* For all preferences in this module, fetch its value from this + module's notebook page and check whether it's valid. */ + return prefs_pref_foreach(module, pref_check, user_data); +} + static guint pref_fetch(pref_t *pref, gpointer user_data) { @@ -918,7 +967,7 @@ pref_fetch(pref_t *pref, gpointer user_data) return 0; } -static void +static guint module_prefs_fetch(module_t *module, gpointer user_data) { gboolean *must_redissect_p = user_data; @@ -933,6 +982,8 @@ module_prefs_fetch(module_t *module, gpointer user_data) could cause packets to be dissected differently. */ if (module->prefs_changed) *must_redissect_p = TRUE; + + return 0; /* keep fetching module preferences */ } static guint @@ -963,19 +1014,40 @@ pref_clean(pref_t *pref, gpointer user_data _U_) return 0; } -static void +static guint module_prefs_clean(module_t *module, gpointer user_data _U_) { /* For all preferences in this module, clean up any cruft allocated for use by the GUI code. */ prefs_pref_foreach(module, pref_clean, NULL); + return 0; /* keep cleaning modules */ } - /* fetch all pref values from all pages */ -static void +static gboolean prefs_main_fetch_all(GtkWidget *dlg, gboolean *must_redissect) { + pref_t *badpref; + + /* First, check that the values are all valid. */ + /* XXX - check the non-registered preferences too */ + switch (prefs_modules_foreach(module_prefs_check, (gpointer)&badpref)) { + + case PREFS_SET_SYNTAX_ERR: + switch (badpref->type) { + + case PREF_UINT: + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, + "The value for \"%s\" is not a valid number.", + badpref->title); + return FALSE; + + default: + g_assert_not_reached(); + break; + } + } + /* Fetch the preferences (i.e., make sure all the values set in all of the preferences panes have been copied to "prefs" and the registered preferences). */ @@ -998,8 +1070,9 @@ prefs_main_fetch_all(GtkWidget *dlg, gboolean *must_redissect) nameres_prefs_fetch(OBJECT_GET_DATA(dlg, E_NAMERES_PAGE_KEY)); prefs_modules_foreach(module_prefs_fetch, must_redissect); -} + return TRUE; +} /* apply all pref values to the real world */ static void @@ -1066,7 +1139,8 @@ prefs_main_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w) { gboolean must_redissect = FALSE; - prefs_main_fetch_all(parent_w, &must_redissect); + if (!prefs_main_fetch_all(parent_w, &must_redissect)) + return; /* Errors in some preference setting */ prefs_main_apply_all(parent_w); @@ -1084,7 +1158,8 @@ prefs_main_apply_cb(GtkWidget *apply_bt _U_, gpointer parent_w) { gboolean must_redissect = FALSE; - prefs_main_fetch_all(parent_w, &must_redissect); + if (!prefs_main_fetch_all(parent_w, &must_redissect)) + return; /* Errors in some preference setting */ prefs_main_apply_all(parent_w); @@ -1102,7 +1177,8 @@ prefs_main_save_cb(GtkWidget *save_bt _U_, gpointer parent_w) char *pf_dir_path; char *pf_path; - prefs_main_fetch_all(parent_w, &must_redissect); + if (!prefs_main_fetch_all(parent_w, &must_redissect)) + return; /* Errors in some preference setting */ /* Create the directory that holds personal configuration files, if necessary. */ @@ -1188,7 +1264,7 @@ pref_revert(pref_t *pref, gpointer user_data) return 0; } -static void +static guint module_prefs_revert(module_t *module, gpointer user_data) { gboolean *must_redissect_p = user_data; @@ -1204,6 +1280,7 @@ module_prefs_revert(module_t *module, gpointer user_data) could cause packets to be dissected differently. */ if (module->prefs_changed) *must_redissect_p = TRUE; + return 0; /* keep processing modules */ } /* cancel button pressed, revert prefs to saved and exit dialog */ @@ -1256,14 +1333,17 @@ struct properties_data { module_t *module; }; -static void +static guint module_search_properties(module_t *module, gpointer user_data) { struct properties_data *p = (struct properties_data *)user_data; /* If this module has the specified title, remember it. */ - if (strcmp(module->title, p->title) == 0) + if (strcmp(module->title, p->title) == 0) { p->module = module; + return 1; /* stops the search */ + } + return 0; } void