aboutsummaryrefslogtreecommitdiffstats
path: root/epan/ftypes
diff options
context:
space:
mode:
authorJeff Morriss <jeff.morriss@ulticom.com>2010-04-30 21:40:39 +0000
committerJeff Morriss <jeff.morriss@ulticom.com>2010-04-30 21:40:39 +0000
commit1b6b831daff3ffaaf1f6f8eff7e195a0bd22ce04 (patch)
tree067086e3f2d41f65ea6bb937b9232eeaee4ab461 /epan/ftypes
parentd13ecdea62e1f01cf1d9dd9ba33d9c328f2b0beb (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')
-rw-r--r--epan/ftypes/ftype-integer.c69
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 */