summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2004-10-16 23:32:24 +0000
committerGuy Harris <guy@alum.mit.edu>2004-10-16 23:32:24 +0000
commit727ad67453a879a58ab46adeee058d2acbbe5c13 (patch)
tree9fe0f60bac0ddcee9a3c48d3ff0ca8003b3ca707
parentde1bcd5d88f4ecd85df770ef5a7a0357b539ee4f (diff)
downloadwireshark-727ad67453a879a58ab46adeee058d2acbbe5c13.tar.gz
Remove the fixed maximum number of subranges in a range_t; dynamically
allocate them to be large enough. Add checks that the numbers in the range fit in a guint32. Check the validity of a range before saving or printing, and report errors in an alert box. Clean up white space. svn path=/trunk/; revision=12320
-rw-r--r--epan/dissectors/packet-tcap.c11
-rw-r--r--epan/prefs-int.h4
-rw-r--r--epan/prefs.c33
-rw-r--r--epan/prefs.h2
-rw-r--r--epan/range.c322
-rw-r--r--epan/range.h15
-rw-r--r--gtk/file_dlg.c24
-rw-r--r--gtk/prefs_dlg.c36
-rw-r--r--gtk/print_dlg.c8
-rw-r--r--gtk/range_utils.c23
-rw-r--r--gtk/range_utils.h8
-rw-r--r--packet-range.c35
-rw-r--r--packet-range.h10
13 files changed, 350 insertions, 181 deletions
diff --git a/epan/dissectors/packet-tcap.c b/epan/dissectors/packet-tcap.c
index d00dcc0084..1938a38ce3 100644
--- a/epan/dissectors/packet-tcap.c
+++ b/epan/dissectors/packet-tcap.c
@@ -67,8 +67,8 @@
Tcap_Standard_Type tcap_standard = ITU_TCAP_STANDARD;
#define MAX_SSN 254
-static range_t global_ssn_range;
-static range_t ssn_range;
+static range_t *global_ssn_range;
+static range_t *ssn_range;
static dissector_handle_t tcap_handle;
@@ -2866,7 +2866,7 @@ proto_register_tcap(void)
/* Set default SSNs */
range_convert_str(&global_ssn_range, "5-12", MAX_SSN);
- memset(&ssn_range, 0, sizeof(ssn_range));
+ ssn_range = range_empty();
prefs_register_range_preference(tcap_module, "ssn", "SCCP SSNs",
"SCCP (and SUA) SSNs to decode as TCAP",
@@ -2913,11 +2913,12 @@ proto_reg_handoff_tcap(void)
} else {
- range_foreach(&ssn_range, range_delete_callback);
+ range_foreach(ssn_range, range_delete_callback);
}
+ g_free(ssn_range);
ssn_range = global_ssn_range;
- range_foreach(&ssn_range, range_add_callback);
+ range_foreach(ssn_range, range_add_callback);
}
diff --git a/epan/prefs-int.h b/epan/prefs-int.h
index e3b5617301..cbcec1d52a 100644
--- a/epan/prefs-int.h
+++ b/epan/prefs-int.h
@@ -68,14 +68,14 @@ struct preference {
gboolean *boolp;
gint *enump;
char **string;
- range_t *rangep;
+ range_t **range;
} varp; /* pointer to variable storing the value */
union {
guint uint;
gboolean boolval;
gint enumval;
char *string;
- range_t rangeval;
+ range_t *range;
} saved_val; /* original value, when editing from the GUI */
union {
guint base; /* input/output base, for PREF_UINT */
diff --git a/epan/prefs.c b/epan/prefs.c
index a44252d47c..38eca978e6 100644
--- a/epan/prefs.c
+++ b/epan/prefs.c
@@ -566,7 +566,7 @@ prefs_register_string_preference(module_t *module, const char *name,
* String preference values should be non-null (as you can't
* keep them null after using the preferences GUI, you can at best
* have them be null strings) and freeable (as we free them
- * if we change them.
+ * if we change them).
*
* If the value is a null pointer, make it a copy of a null
* string, otherwise make it a copy of the value.
@@ -584,7 +584,7 @@ prefs_register_string_preference(module_t *module, const char *name,
*/
void
prefs_register_range_preference(module_t *module, const char *name,
- const char *title, const char *description, range_t *var,
+ const char *title, const char *description, range_t **var,
guint32 max_value)
{
pref_t *preference;
@@ -593,8 +593,22 @@ prefs_register_range_preference(module_t *module, const char *name,
PREF_RANGE);
preference->info.max_value = max_value;
- preference->varp.rangep = var;
- memset(&preference->saved_val.rangeval, 0, sizeof(preference->saved_val.rangeval));
+
+ /*
+ * Range preference values should be non-null (as you can't
+ * keep them null after using the preferences GUI, you can at best
+ * have them be empty ranges) and freeable (as we free them
+ * if we change them).
+ *
+ * If the value is a null pointer, make it an empty range,
+ * otherwise make it a copy of the value.
+ */
+ if (*var == NULL)
+ *var = range_empty();
+ else
+ *var = range_copy(*var);
+ preference->varp.range = var;
+ preference->saved_val.range = NULL;
}
/*
@@ -2020,18 +2034,19 @@ set_pref(gchar *pref_name, gchar *value)
case PREF_RANGE:
{
- range_t newrange;
+ range_t *newrange;
if (range_convert_str(&newrange, value, pref->info.max_value) !=
CVT_NO_ERROR) {
/* XXX - distinguish between CVT_SYNTAX_ERROR and
- CVT_TOO_MANY_SUBRANGES */
+ CVT_NUMBER_TOO_BIG */
return PREFS_SET_SYNTAX_ERR; /* number was bad */
}
- if (!ranges_are_equal(pref->varp.rangep, &newrange)) {
+ if (!ranges_are_equal(*pref->varp.range, newrange)) {
module->prefs_changed = TRUE;
- *pref->varp.rangep = newrange;
+ g_free(*pref->varp.range);
+ *pref->varp.range = newrange;
}
break;
}
@@ -2141,7 +2156,7 @@ write_pref(gpointer data, gpointer user_data)
fprintf(arg->pf, "# A string denoting an positive integer range (e.g., \"1-20,30-40\").\n");
fprintf(arg->pf, "%s.%s: %s\n", arg->module->name, pref->name,
- range_convert_range(pref->varp.rangep, range_string));
+ range_convert_range(*pref->varp.range, range_string));
break;
}
diff --git a/epan/prefs.h b/epan/prefs.h
index f4cb4e023f..b77539c849 100644
--- a/epan/prefs.h
+++ b/epan/prefs.h
@@ -280,7 +280,7 @@ extern void prefs_register_string_preference(module_t *module, const char *name,
* Register a preference with a ranged value.
*/
extern void prefs_register_range_preference(module_t *module, const char *name,
- const char *title, const char *description, range_t *var,
+ const char *title, const char *description, range_t **var,
guint32 max_value);
/*
diff --git a/epan/range.c b/epan/range.c
index dcfef8b548..adf1591239 100644
--- a/epan/range.c
+++ b/epan/range.c
@@ -39,12 +39,27 @@
#include <epan/range.h>
#include <stdio.h>
-/* init the range struct */
-void range_init(range_t *range) {
+/*
+ * GLib 1.2[.x] doesn't define G_MAXUINT32; if it's not defined, we define
+ * it as the maximum 32-bit unsigned number.
+ */
+#ifndef G_MAXUINT32
+#define G_MAXUINT32 ((guint32)0xFFFFFFFFU)
+#endif
+
+/*
+ * Size of the header of a range_t.
+ */
+#define RANGE_HDR_SIZE (sizeof (range_t) - sizeof (range_admin_t))
- range->nranges = 0;
- range->ranges[range->nranges].low = 0L;
- range->ranges[range->nranges].high = 0L;
+/* Allocate an empty range. */
+range_t *range_empty(void)
+{
+ range_t *range;
+
+ range = g_malloc(RANGE_HDR_SIZE);
+ range->nranges = 0;
+ return range;
}
/******************** Range Entry Parser *********************************/
@@ -54,10 +69,11 @@ void range_init(range_t *range) {
* The parameter 'max_value' specifies the maximum value in a
* range.
*
- * This function fills the array range->ranges containing low and high values
- * with the number of ranges being range->nranges. After having called this
- * function, the function value_is_in_range() determines whether a given
- * number is within the range or not.
+ * This function allocates a range_t large enough to hold the number
+ * of ranges specified, and fills the array range->ranges containing
+ * low and high values with the number of ranges being range->nranges.
+ * After having called this function, the function value_is_in_range()
+ * determines whether a given number is within the range or not.
*
* In case of a single number, we make a range where low is equal to high.
* We take care on wrongly entered ranges; opposite order will be taken
@@ -72,127 +88,158 @@ void range_init(range_t *range) {
* - All values
*/
-convert_ret_t
-range_convert_str(range_t *range, const gchar *es, guint32 max_value)
+convert_ret_t range_convert_str(range_t **rangep, const gchar *es,
+ guint32 max_value)
{
- const gchar *p;
- char *endp;
- gchar c;
- guint i;
- guint32 tmp;
- unsigned long val;
-
- /* Reset the number of ranges we are going to find */
- range->nranges = 0;
- range->ranges[range->nranges].low = 0L;
- range->ranges[range->nranges].high = 0L;
-
- /* Process the ranges separately until we get a comma or end of string.
- *
- * We build a structure array called ranges of high and low values. After the
- * following loop, we have the nranges variable which tells how many ranges
- * were found. The number of individual ranges is limited to 'MaxRanges'
- */
-
- p = es;
- for (;;) {
- /* Skip white space. */
- while ((c = *p) == ' ' || c == '\t')
- p++;
- if (c == '\0')
- break;
-
- /* This must be a subrange. */
- if (range->nranges == MaxRange) {
- /* We've filled up the structure; no room for any more. */
- return CVT_TOO_MANY_SUBRANGES;
- }
-
- if (c == '-') {
- /* Subrange starts with 1. */
- range->ranges[range->nranges].low = 1;
- } else {
- /* Subrange starts with the specified number */
- val = strtol(p, &endp, 10);
- if (p == endp) {
- /* That wasn't a valid number. */
- return CVT_SYNTAX_ERROR;
- }
- p = endp;
- range->ranges[range->nranges].low = val;
-
- /* Skip white space. */
- while ((c = *p) == ' ' || c == '\t')
- p++;
- }
-
- if (c == '-') {
- /* There's a hyphen in the range. Skip past it. */
- p++;
-
- /* Skip white space. */
- while ((c = *p) == ' ' || c == '\t')
- p++;
-
- if (c == ',' || c == '\0') {
- /*
- * End of subrange string; that means the subrange ends
- * with max_value.
- */
- range->ranges[range->nranges].high = max_value;
- } else {
- /* Subrange ends with the specified number. */
- val = strtol(p, &endp, 10);
- if (p == endp) {
- /* That wasn't a valid number. */
- return CVT_SYNTAX_ERROR;
- }
- p = endp;
- range->ranges[range->nranges].high = val;
-
- /* Skip white space. */
- while ((c = *p) == ' ' || c == '\t')
- p++;
- }
- } else if (c == ',' || c == '\0') {
- /*
- * End of subrange string; that means there's no hyphen
- * in the subrange, so the start and the end are the same.
- */
- range->ranges[range->nranges].high =
- range->ranges[range->nranges].low;
- } else {
- /* Invalid character. */
- return CVT_SYNTAX_ERROR;
- }
- range->nranges++;
-
- if (c == ',') {
- /* Subrange is followed by a comma; skip it. */
- p++;
- }
- }
-
- /* Now we are going through the low and high values, and check
- * whether they are in a proper order. Low should be equal or lower
- * than high. So, go through the loop and swap if needed.
- */
- for (i=0; i < range->nranges; i++) {
- if (range->ranges[i].low > range->ranges[i].high) {
- tmp = range->ranges[i].low;
- range->ranges[i].low = range->ranges[i].high;
- range->ranges[i].high = tmp;
- }
- }
-
- /* In case we want to know what the result ranges are :
- *
- * for (i=0; i < range->nranges; i++) {
- * printf("Function : range_convert_str L=%u \t H=%u\n",range->ranges[i].low,range->ranges[i].high);
- * }
- *
- */
- return CVT_NO_ERROR;
+ range_t *range;
+ guint nranges;
+ const gchar *p;
+ char *endp;
+ gchar c;
+ guint i;
+ guint32 tmp;
+ unsigned long val;
+
+ /* Allocate a range; this has room for one subrange. */
+ range = g_malloc(RANGE_HDR_SIZE + sizeof (range_admin_t));
+ range->nranges = 0;
+ nranges = 1;
+
+ /* Process the ranges separately until we get a comma or end of string.
+ *
+ * We build a structure array called ranges of high and low values. After the
+ * following loop, we have the nranges variable which tells how many ranges
+ * were found. The number of individual ranges is limited to 'MaxRanges'
+ */
+
+ p = es;
+ for (;;) {
+ /* Skip white space. */
+ while ((c = *p) == ' ' || c == '\t')
+ p++;
+ if (c == '\0')
+ break;
+
+ /* This must be a subrange. Make sure we have room for it. */
+ if (range->nranges >= nranges) {
+ /* Grow the structure.
+ * 4 is an arbitrarily chosen number.
+ * We start with 1, under the assumption that people
+ * will often give a single number or range, and then
+ * proceed to keep it a multiple of 4.
+ */
+ if (nranges == 1)
+ nranges = 4;
+ else
+ nranges += 4;
+ range = g_realloc(range, RANGE_HDR_SIZE +
+ nranges*sizeof (range_admin_t));
+ }
+
+ if (c == '-') {
+ /* Subrange starts with 1. */
+ range->ranges[range->nranges].low = 1;
+ } else if (isdigit((unsigned char)c)) {
+ /* Subrange starts with the specified number */
+ val = strtol(p, &endp, 10);
+ if (p == endp) {
+ /* That wasn't a valid number. */
+ g_free(range);
+ return CVT_SYNTAX_ERROR;
+ }
+ if (val > G_MAXUINT32) {
+ /* That was valid, but it's too big. */
+ g_free(range);
+ return CVT_NUMBER_TOO_BIG;
+ }
+ p = endp;
+ range->ranges[range->nranges].low = val;
+
+ /* Skip white space. */
+ while ((c = *p) == ' ' || c == '\t')
+ p++;
+ } else {
+ /* Neither empty nor a number. */
+ g_free(range);
+ return CVT_SYNTAX_ERROR;
+ }
+
+ if (c == '-') {
+ /* There's a hyphen in the range. Skip past it. */
+ p++;
+
+ /* Skip white space. */
+ while ((c = *p) == ' ' || c == '\t')
+ p++;
+
+ if (c == ',' || c == '\0') {
+ /* End of subrange string; that means the subrange ends
+ * with max_value.
+ */
+ range->ranges[range->nranges].high = max_value;
+ } else if (isdigit((unsigned char)c)) {
+ /* Subrange ends with the specified number. */
+ val = strtoul(p, &endp, 10);
+ if (p == endp) {
+ /* That wasn't a valid number. */
+ g_free(range);
+ return CVT_SYNTAX_ERROR;
+ }
+ if (val > G_MAXUINT32) {
+ /* That was valid, but it's too big. */
+ g_free(range);
+ return CVT_NUMBER_TOO_BIG;
+ }
+ p = endp;
+ range->ranges[range->nranges].high = val;
+
+ /* Skip white space. */
+ while ((c = *p) == ' ' || c == '\t')
+ p++;
+ } else {
+ /* Neither empty nor a number. */
+ g_free(range);
+ return CVT_SYNTAX_ERROR;
+ }
+ } else if (c == ',' || c == '\0') {
+ /* End of subrange string; that means there's no hyphen
+ * in the subrange, so the start and the end are the same.
+ */
+ range->ranges[range->nranges].high = range->ranges[range->nranges].low;
+ } else {
+ /* Invalid character. */
+ g_free(range);
+ return CVT_SYNTAX_ERROR;
+ }
+ range->nranges++;
+
+ if (c == ',') {
+ /* Subrange is followed by a comma; skip it. */
+ p++;
+ }
+ }
+
+ /* Now we are going through the low and high values, and check
+ * whether they are in a proper order. Low should be equal or lower
+ * than high. So, go through the loop and swap if needed.
+ */
+ for (i=0; i < range->nranges; i++) {
+ if (range->ranges[i].low > range->ranges[i].high) {
+ tmp = range->ranges[i].low;
+ range->ranges[i].low = range->ranges[i].high;
+ range->ranges[i].high = tmp;
+ }
+ }
+
+ /* In case we want to know what the result ranges are :
+ *
+ * for (i=0; i < range->nranges; i++) {
+ * printf("Function : range_convert_str L=%u \t H=%u\n",range->ranges[i].low,range->ranges[i].high);
+ * }
+ *
+ */
+ *rangep = range;
+ return CVT_NO_ERROR;
} /* range_convert_str */
/* This function returns TRUE if a given value is within one of the ranges
@@ -204,7 +251,7 @@ gboolean value_is_in_range(range_t *range, guint32 val)
for (i=0; i < range->nranges; i++) {
if (val >= range->ranges[i].low && val <= range->ranges[i].high)
- return TRUE;
+ return TRUE;
}
return(FALSE);
}
@@ -240,7 +287,7 @@ range_foreach(range_t *range, void (*callback)(guint32 val))
for (i=0; i < range->nranges; i++) {
for (j = range->ranges[i].low; j <= range->ranges[i].high; j++)
- callback(j);
+ callback(j);
}
}
@@ -265,6 +312,18 @@ range_convert_range(range_t *range, char *string)
}
+/* Create a copy of a range. */
+range_t *range_copy(range_t *src)
+{
+ range_t *dst;
+ size_t range_size;
+
+ range_size = RANGE_HDR_SIZE + src->nranges*sizeof (range_admin_t);
+ dst = g_malloc(range_size);
+ memcpy(dst, src, range_size);
+ return dst;
+}
+
#if 0
/* This is a debug function to check the range functionality */
static void value_is_in_range_check(range_t *range, guint32 val)
@@ -280,3 +339,4 @@ static void value_is_in_range_check(range_t *range, guint32 val)
}
}
#endif
+
diff --git a/epan/range.h b/epan/range.h
index 8f6f43f6ba..de88cfb77a 100644
--- a/epan/range.h
+++ b/epan/range.h
@@ -32,9 +32,6 @@
#include <epan/frame_data.h>
-/* Range parser variables */
-#define MaxRange 30
-
#define MAXRANGESTRING 255
typedef struct range_admin_tag {
@@ -44,8 +41,8 @@ typedef struct range_admin_tag {
typedef struct range {
/* user specified range(s) */
- guint nranges; /* number of entries in ranges (0 based) */
- range_admin_t ranges[MaxRange];
+ guint nranges; /* number of entries in ranges */
+ range_admin_t ranges[1]; /* variable-length array */
} range_t;
/*
@@ -54,12 +51,12 @@ typedef struct range {
typedef enum {
CVT_NO_ERROR,
CVT_SYNTAX_ERROR,
- CVT_TOO_MANY_SUBRANGES
+ CVT_NUMBER_TOO_BIG
} convert_ret_t;
-extern void range_init(range_t *range);
+extern range_t *range_empty(void);
-extern convert_ret_t range_convert_str(range_t *range, const gchar *es,
+extern convert_ret_t range_convert_str(range_t **range, const gchar *es,
guint32 max_value);
extern gboolean value_is_in_range(range_t *range, guint32 val);
@@ -70,4 +67,6 @@ extern void range_foreach(range_t *range, void (*callback)(guint32 val));
extern char *range_convert_range(range_t *range, char *string);
+extern range_t *range_copy(range_t *src);
+
#endif /* __RANGE_H__ */
diff --git a/gtk/file_dlg.c b/gtk/file_dlg.c
index 565754d722..535e84e9fc 100644
--- a/gtk/file_dlg.c
+++ b/gtk/file_dlg.c
@@ -1385,6 +1385,24 @@ file_save_as_ok_cb(GtkWidget *w _U_, gpointer fs) {
return;
}
+ /* Check whether the range is valid. */
+ if (!range_check_validity(&range)) {
+ /* The range isn't valid; don't dismiss the open dialog box,
+ just leave it around so that the user can, after they
+ dismiss the alert box popped up for the error, try again. */
+ g_free(cf_name);
+#if (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 4) || GTK_MAJOR_VERSION > 2
+ /* XXX - as we cannot start a new event loop (using gtk_dialog_run()),
+ * as this will prevent the user from closing the now existing error
+ * message, simply close the dialog (this is the best we can do here). */
+ if (file_save_as_w)
+ window_destroy(GTK_WIDGET (fs));
+#else
+ gtk_widget_show(GTK_WIDGET (fs));
+#endif
+ return;
+ }
+
/* don't show the dialog while saving */
gtk_widget_hide(GTK_WIDGET (fs));
@@ -1396,9 +1414,9 @@ file_save_as_ok_cb(GtkWidget *w _U_, gpointer fs) {
dismiss the alert box popped up for the error, try again. */
g_free(cf_name);
#if (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 4) || GTK_MAJOR_VERSION > 2
- /* as we cannot start a new event loop (using gtk_dialog_run()), as this
- * will prevent the user from closing the now existing error message,
- * simply close the dialog (this is the best we can do here). */
+ /* XXX - as we cannot start a new event loop (using gtk_dialog_run()),
+ * as this will prevent the user from closing the now existing error
+ * message, simply close the dialog (this is the best we can do here). */
if (file_save_as_w)
window_destroy(GTK_WIDGET (fs));
#else
diff --git a/gtk/prefs_dlg.c b/gtk/prefs_dlg.c
index c5c305ed16..f2b31f4c60 100644
--- a/gtk/prefs_dlg.c
+++ b/gtk/prefs_dlg.c
@@ -206,8 +206,10 @@ pref_show(pref_t *pref, gpointer user_data)
{
char range_string[MAXRANGESTRING];
- pref->saved_val.rangeval = *pref->varp.rangep;
- range_convert_range(pref->varp.rangep, range_string);
+ if (pref->saved_val.range != NULL)
+ g_free(pref->saved_val.range);
+ pref->saved_val.range = range_copy(*pref->varp.range);
+ range_convert_range(*pref->varp.range, range_string);
pref->control = create_preference_entry(main_tb, pref->ordinal,
label_string, pref->description,
range_string);
@@ -901,14 +903,15 @@ pref_check(pref_t *pref, gpointer user_data)
case PREF_RANGE:
str_val = gtk_entry_get_text(GTK_ENTRY(pref->control));
- if (strlen(str_val)) {
- range_t newrange;
+ if (strlen(str_val) != 0) {
+ range_t *newrange;
if (range_convert_str(&newrange, str_val, pref->info.max_value) !=
CVT_NO_ERROR) {
*badpref = pref;
return PREFS_SET_SYNTAX_ERR; /* range was bad */
}
+ g_free(newrange);
}
break;
@@ -988,21 +991,24 @@ pref_fetch(pref_t *pref, gpointer user_data)
case PREF_RANGE:
{
- range_t newrange;
+ range_t *newrange;
convert_ret_t ret;
str_val = gtk_entry_get_text(GTK_ENTRY(pref->control));
ret = range_convert_str(&newrange, str_val, pref->info.max_value);
-#if 0
if (ret != CVT_NO_ERROR)
+#if 0
return PREFS_SET_SYNTAX_ERR; /* range was bad */
+#else
+ return 0; /* XXX - should fail */
#endif
- if (!ranges_are_equal(pref->varp.rangep, &newrange))
- {
+ if (!ranges_are_equal(*pref->varp.range, newrange)) {
*pref_changed_p = TRUE;
- *pref->varp.rangep = newrange;
- }
+ g_free(*pref->varp.range);
+ *pref->varp.range = newrange;
+ } else
+ g_free(newrange);
break;
}
@@ -1055,6 +1061,10 @@ pref_clean(pref_t *pref, gpointer user_data _U_)
break;
case PREF_RANGE:
+ if (pref->saved_val.range != NULL) {
+ g_free(pref->saved_val.range);
+ pref->saved_val.range = NULL;
+ }
break;
case PREF_OBSOLETE:
@@ -1314,10 +1324,10 @@ pref_revert(pref_t *pref, gpointer user_data)
break;
case PREF_RANGE:
- if (!ranges_are_equal(pref->varp.rangep, &pref->saved_val.rangeval))
- {
+ if (!ranges_are_equal(*pref->varp.range, pref->saved_val.range)) {
*pref_changed_p = TRUE;
- *pref->varp.rangep = pref->saved_val.rangeval;
+ g_free(*pref->varp.range);
+ *pref->varp.range = range_copy(pref->saved_val.range);
}
break;
diff --git a/gtk/print_dlg.c b/gtk/print_dlg.c
index 938c236e26..1dd30a5b36 100644
--- a/gtk/print_dlg.c
+++ b/gtk/print_dlg.c
@@ -748,6 +748,14 @@ print_ok_cb(GtkWidget *ok_bt, gpointer parent_w)
args = (print_args_t *)OBJECT_GET_DATA(ok_bt, PRINT_ARGS_KEY);
+ /* Check whether the range is valid. */
+ if (!range_check_validity(&args->range)) {
+ /* The range isn't valid; don't dismiss the print/export dialog box,
+ just leave it around so that the user can, after they
+ dismiss the alert box popped up for the error, try again. */
+ return;
+ }
+
button = (GtkWidget *)OBJECT_GET_DATA(ok_bt, PRINT_DEST_CB_KEY);
args->to_file = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (button));
diff --git a/gtk/range_utils.c b/gtk/range_utils.c
index 824635d000..b35894275c 100644
--- a/gtk/range_utils.c
+++ b/gtk/range_utils.c
@@ -36,6 +36,7 @@
#include "ui_util.h"
#include "dlg_utils.h"
#include "compat_macros.h"
+#include "simple_dialog.h"
#define RANGE_VALUES_KEY "range_values"
@@ -58,7 +59,29 @@
#define RANGE_SELECT_USER_D_KEY "range_select_user_range_d_lb"
#define RANGE_SELECT_USER_ENTRY_KEY "range_select_user_range_entry"
+gboolean
+range_check_validity(packet_range_t *range)
+{
+ switch (packet_range_check(range)) {
+
+ case CVT_NO_ERROR:
+ return TRUE;
+
+ case CVT_SYNTAX_ERROR:
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+ "The specified range of packets isn't a valid range.");
+ return FALSE;
+
+ case CVT_NUMBER_TOO_BIG:
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+ "The specified range of packets has a packet number that's too large.");
+ return FALSE;
+ default:
+ g_assert_not_reached();
+ return FALSE;
+ }
+}
/* update all "dynamic" things */
void
diff --git a/gtk/range_utils.h b/gtk/range_utils.h
index 3bd4303f4b..fded166d46 100644
--- a/gtk/range_utils.h
+++ b/gtk/range_utils.h
@@ -31,6 +31,14 @@
* Packet range widget used for example in the "Save" and "Print" dialogs.
*/
+/** Check the validity of a packet_range_t, and put up an alert box if
+ ** it's not valid.
+ *
+ * @param range the range to check
+ * @return a Boolean that's TRUE if it's valid and FALSE if it isn't
+ */
+extern gboolean range_check_validity(packet_range_t *range);
+
/** Create a new range widget.
*
* @param range the range to set
diff --git a/packet-range.c b/packet-range.c
index 0171b5115a..b39c6fce8f 100644
--- a/packet-range.c
+++ b/packet-range.c
@@ -131,7 +131,7 @@ void packet_range_calc(packet_range_t *range) {
/* (re-)calculate the user specified packet range counts */
-void packet_range_calc_user(packet_range_t *range) {
+static void packet_range_calc_user(packet_range_t *range) {
guint32 current_count;
frame_data *packet;
@@ -142,7 +142,7 @@ void packet_range_calc_user(packet_range_t *range) {
for(packet = cfile.plist; packet != NULL; packet = packet->next) {
current_count++;
- if (value_is_in_range(&range->user_range, current_count)) {
+ if (value_is_in_range(range->user_range, current_count)) {
range->user_range_cnt++;
if (packet->flags.passed_dfilter) {
range->displayed_user_range_cnt++;
@@ -157,15 +157,25 @@ void packet_range_init(packet_range_t *range) {
range->process = range_process_all;
range->process_filtered = FALSE;
- range_init(&range->user_range);
+ range->user_range = range_empty();
/* calculate all packet range counters */
packet_range_calc(range);
packet_range_calc_user(range);
}
+/* check whether the packet range is OK */
+convert_ret_t packet_range_check(packet_range_t *range) {
+ if (range->process == range_process_user_range && range->user_range == NULL) {
+ /* Not valid - return the error. */
+ return range->user_range_status;
+ }
+ return CVT_NO_ERROR;
+}
+
/* init the processing run */
void packet_range_process_init(packet_range_t *range) {
+ /* Check that, if an explicit range was selected, it's valid. */
/* "enumeration" values */
range->marked_range_active = FALSE;
range->selected_done = FALSE;
@@ -219,7 +229,7 @@ range_process_e packet_range_process_packet(packet_range_t *range, frame_data *f
}
break;
case(range_process_user_range):
- if (value_is_in_range(&range->user_range, fdata->num) == FALSE) {
+ if (value_is_in_range(range->user_range, fdata->num) == FALSE) {
return range_process_next;
}
break;
@@ -246,8 +256,21 @@ range_process_e packet_range_process_packet(packet_range_t *range, frame_data *f
void packet_range_convert_str(packet_range_t *range, const gchar *es)
{
- /* XXX - check for errors */
- range_convert_str(&range->user_range, es, cfile.count);
+ range_t *new_range;
+ convert_ret_t ret;
+
+ if (range->user_range != NULL)
+ g_free(range->user_range);
+ ret = range_convert_str(&new_range, es, cfile.count);
+ if (ret != CVT_NO_ERROR) {
+ /* range isn't valid */
+ range->user_range = NULL;
+ range->user_range_status = ret;
+ range->user_range_cnt = 0L;
+ range->displayed_user_range_cnt = 0L;
+ return;
+ }
+ range->user_range = new_range;
/* calculate new user specified packet range counts */
packet_range_calc_user(range);
diff --git a/packet-range.h b/packet-range.h
index 3007d215c8..b4e9f66bc9 100644
--- a/packet-range.h
+++ b/packet-range.h
@@ -49,8 +49,9 @@ typedef struct packet_range_tag {
packet_range_e process; /* which range to process */
gboolean process_filtered; /* captured or filtered packets */
- /* user specified range(s) */
- range_t user_range;
+ /* user specified range(s) and, if null, error status */
+ range_t *user_range;
+ convert_ret_t user_range_status;
/* calculated values */
guint32 selected_packet; /* the currently selected packet */
@@ -82,8 +83,11 @@ typedef enum {
/* init the range structure */
extern void packet_range_init(packet_range_t *range);
+/* check whether the packet range is OK */
+extern convert_ret_t packet_range_check(packet_range_t *range);
+
/* init the processing run */
-void packet_range_process_init(packet_range_t *range);
+extern void packet_range_process_init(packet_range_t *range);
/* do we have to process all packets? */
extern gboolean packet_range_process_all(packet_range_t *range);