diff options
author | Jeff Morriss <jeff.morriss@ulticom.com> | 2010-04-30 21:40:39 +0000 |
---|---|---|
committer | Jeff Morriss <jeff.morriss@ulticom.com> | 2010-04-30 21:40:39 +0000 |
commit | 1b6b831daff3ffaaf1f6f8eff7e195a0bd22ce04 (patch) | |
tree | 067086e3f2d41f65ea6bb937b9232eeaee4ab461 /epan/ftypes/ftype-integer.c | |
parent | d13ecdea62e1f01cf1d9dd9ba33d9c328f2b0beb (diff) |
Fix https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=1696 :
The change put in with rev 11382 meant that, on 64-bit systems, we could not
parse negative numbers into integers (since -1 taken as an unsigned 64-bit
number is (significantly) larger than G_MAX_UINT32).
To fix this, split the val_from_unparsed() routine for integers into two
routines: one for signed and one for unsigned; each routine can then do the
appropriate "is this bigger than what fits in a *32?" test.
svn path=/trunk/; revision=32616
Diffstat (limited to 'epan/ftypes/ftype-integer.c')
-rw-r--r-- | epan/ftypes/ftype-integer.c | 69 |
1 files changed, 57 insertions, 12 deletions
diff --git a/epan/ftypes/ftype-integer.c b/epan/ftypes/ftype-integer.c index 87d5888c65..c1e962de48 100644 --- a/epan/ftypes/ftype-integer.c +++ b/epan/ftypes/ftype-integer.c @@ -62,7 +62,7 @@ get_sinteger(fvalue_t *fv) static gboolean -val_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc) +uint_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc) { unsigned long value; char *endptr; @@ -106,6 +106,51 @@ val_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFu return TRUE; } +static gboolean +sint_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc) +{ + long value; + char *endptr; + + errno = 0; + value = strtol(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 == LONG_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_MAXINT32) { + /* + * Fits in an long, but not in a gint32 + * (a long might be 64 bits). + */ + if (logfunc != NULL) + logfunc("\"%s\" causes an integer overflow.", s); + return FALSE; + } + + fv->value.sinteger = (gint32)value; + return TRUE; +} + static int integer_repr_len(fvalue_t *fv _U_, ftrepr_t rtype _U_) { @@ -149,7 +194,7 @@ ipxnet_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, Lo * up as an IPX network name if it does, and if that fails, * we'll log a message. */ - if (val_from_unparsed(fv, s, TRUE, NULL)) { + if (uint_from_unparsed(fv, s, TRUE, NULL)) { return TRUE; } @@ -457,7 +502,7 @@ ftype_register_integers(void) 1, /* wire_size */ int_fvalue_new, /* new_value */ NULL, /* free_value */ - val_from_unparsed, /* val_from_unparsed */ + uint_from_unparsed, /* val_from_unparsed */ NULL, /* val_from_string */ uinteger_to_repr, /* val_to_string_repr */ uinteger_repr_len, /* len_string_repr */ @@ -494,7 +539,7 @@ ftype_register_integers(void) 2, /* wire_size */ int_fvalue_new, /* new_value */ NULL, /* free_value */ - val_from_unparsed, /* val_from_unparsed */ + uint_from_unparsed, /* val_from_unparsed */ NULL, /* val_from_string */ uinteger_to_repr, /* val_to_string_repr */ uinteger_repr_len, /* len_string_repr */ @@ -531,7 +576,7 @@ ftype_register_integers(void) 3, /* wire_size */ int_fvalue_new, /* new_value */ NULL, /* free_value */ - val_from_unparsed, /* val_from_unparsed */ + uint_from_unparsed, /* val_from_unparsed */ NULL, /* val_from_string */ uinteger_to_repr, /* val_to_string_repr */ uinteger_repr_len, /* len_string_repr */ @@ -568,7 +613,7 @@ ftype_register_integers(void) 4, /* wire_size */ int_fvalue_new, /* new_value */ NULL, /* free_value */ - val_from_unparsed, /* val_from_unparsed */ + uint_from_unparsed, /* val_from_unparsed */ NULL, /* val_from_string */ uinteger_to_repr, /* val_to_string_repr */ uinteger_repr_len, /* len_string_repr */ @@ -642,7 +687,7 @@ ftype_register_integers(void) 1, /* wire_size */ int_fvalue_new, /* new_value */ NULL, /* free_value */ - val_from_unparsed, /* val_from_unparsed */ + sint_from_unparsed, /* val_from_unparsed */ NULL, /* val_from_string */ integer_to_repr, /* val_to_string_repr */ integer_repr_len, /* len_string_repr */ @@ -679,7 +724,7 @@ ftype_register_integers(void) 2, /* wire_size */ int_fvalue_new, /* new_value */ NULL, /* free_value */ - val_from_unparsed, /* val_from_unparsed */ + sint_from_unparsed, /* val_from_unparsed */ NULL, /* val_from_string */ integer_to_repr, /* val_to_string_repr */ integer_repr_len, /* len_string_repr */ @@ -716,7 +761,7 @@ ftype_register_integers(void) 3, /* wire_size */ int_fvalue_new, /* new_value */ NULL, /* free_value */ - val_from_unparsed, /* val_from_unparsed */ + sint_from_unparsed, /* val_from_unparsed */ NULL, /* val_from_string */ integer_to_repr, /* val_to_string_repr */ integer_repr_len, /* len_string_repr */ @@ -753,7 +798,7 @@ ftype_register_integers(void) 4, /* wire_size */ int_fvalue_new, /* new_value */ NULL, /* free_value */ - val_from_unparsed, /* val_from_unparsed */ + sint_from_unparsed, /* val_from_unparsed */ NULL, /* val_from_string */ integer_to_repr, /* val_to_string_repr */ integer_repr_len, /* len_string_repr */ @@ -827,7 +872,7 @@ ftype_register_integers(void) 0, /* wire_size */ boolean_fvalue_new, /* new_value */ NULL, /* free_value */ - val_from_unparsed, /* val_from_unparsed */ + uint_from_unparsed, /* val_from_unparsed */ NULL, /* val_from_string */ boolean_to_repr, /* val_to_string_repr */ boolean_repr_len, /* len_string_repr */ @@ -903,7 +948,7 @@ ftype_register_integers(void) 4, /* wire_size */ int_fvalue_new, /* new_value */ NULL, /* free_value */ - val_from_unparsed, /* val_from_unparsed */ + uint_from_unparsed, /* val_from_unparsed */ NULL, /* val_from_string */ uinteger_to_repr, /* val_to_string_repr */ uinteger_repr_len, /* len_string_repr */ |