diff --git a/epan/ftypes/ftype-integer.c b/epan/ftypes/ftype-integer.c index cdc7085..75cf1f6 100644 --- a/epan/ftypes/ftype-integer.c +++ b/epan/ftypes/ftype-integer.c @@ -67,6 +67,16 @@ uint_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogF unsigned long value; char *endptr; + if (strchr (s, '-') && strtol(s, NULL, 0) < 0) { + /* + * Probably a negative integer, but will be + * "converted in the obvious manner" by strtoul(). + */ + if (logfunc != NULL) + logfunc("\"%s\" causes an integer underflow.", s); + return FALSE; + } + errno = 0; value = strtoul(s, &endptr, 0); @@ -112,6 +122,16 @@ sint_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogF long value; char *endptr; + if (!strchr (s, '-') && strtoull(s, NULL, 0) > G_MAXINT32) { + /* + * Probably a positive integer > G_MAXINT32, but will be + * "converted in the obvious manner" by strtol(). + */ + if (logfunc != NULL) + logfunc("\"%s\" causes an integer overflow.", s); + return FALSE; + } + errno = 0; value = strtol(s, &endptr, 0); @@ -314,11 +334,21 @@ get_integer64(fvalue_t *fv) } static gboolean -val64_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc) +uint64_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc) { guint64 value; char *endptr; + if (strchr (s, '-') && g_ascii_strtoll(s, NULL, 0) < 0) { + /* + * Probably a negative integer, but will be + * "converted in the obvious manner" by g_ascii_strtoull(). + */ + if (logfunc != NULL) + logfunc("\"%s\" causes an integer underflow.", s); + return FALSE; + } + errno = 0; value = g_ascii_strtoull(s, &endptr, 0); @@ -330,9 +360,8 @@ val64_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, Log } if (errno == ERANGE) { if (logfunc != NULL) { - if (value == ULONG_MAX) { - logfunc("\"%s\" causes an integer overflow.", - s); + if (value == G_MAXUINT64) { + logfunc("\"%s\" causes an integer overflow.", s); } else { /* @@ -344,17 +373,53 @@ val64_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, Log } return FALSE; } - if (value > G_MAXUINT64) { + + fv->value.integer64 = value; + return TRUE; +} + +static gboolean +sint64_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc) +{ + gint64 value; + char *endptr; + + if (!strchr (s, '-') && g_ascii_strtoull(s, NULL, 0) > G_MAXINT64) { /* - * Fits in an unsigned long, but not in a guint64 - * (unlikely, but not impossible). + * Probably a positive integer > G_MAXINT64, but will be + * "converted in the obvious manner" by g_ascii_strtoll(). */ if (logfunc != NULL) logfunc("\"%s\" causes an integer overflow.", s); return FALSE; } - fv->value.integer64 = value; + errno = 0; + value = g_ascii_strtoll(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); + return FALSE; + } + if (errno == ERANGE) { + if (logfunc != NULL) { + if (value == G_MAXINT64) { + logfunc("\"%s\" causes an integer overflow.", s); + } + else { + /* + * XXX - can "strtol()" set errno to + * ERANGE without returning LONG_MAX? + */ + logfunc("\"%s\" is not an integer.", s); + } + } + return FALSE; + } + + fv->value.integer64 = (guint64)value; return TRUE; } @@ -508,7 +573,7 @@ eui64_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, Log * up as an EUI64 Address if it does, and if that fails, * we'll log a message. */ - if (val64_from_unparsed(fv, s, TRUE, NULL)) { + if (uint64_from_unparsed(fv, s, TRUE, NULL)) { return TRUE; } @@ -694,7 +759,7 @@ ftype_register_integers(void) 8, /* wire_size */ int64_fvalue_new, /* new_value */ NULL, /* free_value */ - val64_from_unparsed, /* val_from_unparsed */ + uint64_from_unparsed, /* val_from_unparsed */ NULL, /* val_from_string */ uinteger64_to_repr, /* val_to_string_repr */ uinteger64_repr_len, /* len_string_repr */ @@ -879,7 +944,7 @@ ftype_register_integers(void) 8, /* wire_size */ int64_fvalue_new, /* new_value */ NULL, /* free_value */ - val64_from_unparsed, /* val_from_unparsed */ + sint64_from_unparsed, /* val_from_unparsed */ NULL, /* val_from_string */ integer64_to_repr, /* val_to_string_repr */ integer64_repr_len, /* len_string_repr */