diff options
-rw-r--r-- | epan/dfilter/scanner.l | 25 | ||||
-rw-r--r-- | epan/ftypes/ftype-integer.c | 22 |
2 files changed, 42 insertions, 5 deletions
diff --git a/epan/dfilter/scanner.l b/epan/dfilter/scanner.l index 0483d12bc9..2d4e6ac9a4 100644 --- a/epan/dfilter/scanner.l +++ b/epan/dfilter/scanner.l @@ -322,11 +322,12 @@ static gboolean str_to_gint32(char *s, gint32* pint) { char *endptr; - gint32 integer; + long integer; + errno = 0; integer = strtol(s, &endptr, 0); - if (endptr == s || *endptr != '\0') { + if (errno == EINVAL || endptr == s || *endptr != '\0') { /* This isn't a valid number. */ dfilter_fail("\"%s\" is not a valid number.", s); return FALSE; @@ -339,10 +340,30 @@ str_to_gint32(char *s, gint32* pint) dfilter_fail("\"%s\" causes an integer underflow.", s); } else { + /* + * XXX - can "strtol()" set errno to ERANGE without + * returning LONG_MAX or LONG_MIN? + */ dfilter_fail("\"%s\" is not an integer.", s); } return FALSE; } + if (integer > G_MAXINT32) { + /* + * Fits in a long, but not in a gint32 (a long might be + * 64 bits). + */ + dfilter_fail("\"%s\" causes an integer overflow.", s); + return FALSE; + } + if (integer < G_MININT32) { + /* + * Fits in a long, but not in a gint32 (a long might be + * 64 bits). + */ + dfilter_fail("\"%s\" causes an integer underflow.", s); + return FALSE; + } *pint = integer; return TRUE; diff --git a/epan/ftypes/ftype-integer.c b/epan/ftypes/ftype-integer.c index 9645a7b41a..7802b7b919 100644 --- a/epan/ftypes/ftype-integer.c +++ b/epan/ftypes/ftype-integer.c @@ -51,11 +51,13 @@ get_integer(fvalue_t *fv) static gboolean val_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc) { + unsigned long value; char *endptr; - fv->value.integer = strtoul(s, &endptr, 0); + errno = 0; + value = strtoul(s, &endptr, 0); - if (endptr == s || *endptr != '\0') { + if (errno == EINVAL || endptr == s || *endptr != '\0') { /* This isn't a valid number. */ if (logfunc != NULL) logfunc("\"%s\" is not a valid number.", s); @@ -63,17 +65,31 @@ val_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFu } if (errno == ERANGE) { if (logfunc != NULL) { - if (fv->value.integer == ULONG_MAX) { + if (value == ULONG_MAX) { logfunc("\"%s\" causes an integer overflow.", s); } else { + /* + * XXX - can "strtoul()" set errno to + * ERANGE without returning ULONG_MAX? + */ logfunc("\"%s\" is not an integer.", s); } } return FALSE; } + if (value > G_MAXUINT32) { + /* + * Fits in an unsigned long, but not in a guint32 + * (an unsigned long might be 64 bits). + */ + if (logfunc != NULL) + logfunc("\"%s\" causes an integer overflow.", s); + return FALSE; + } + fv->value.integer = value; return TRUE; } |