aboutsummaryrefslogtreecommitdiffstats
path: root/epan/ftypes/ftype-integer.c
diff options
context:
space:
mode:
authorStig Bjørlykke <stig@bjorlykke.org>2011-10-28 20:14:13 +0000
committerStig Bjørlykke <stig@bjorlykke.org>2011-10-28 20:14:13 +0000
commit3e241efba3e14ee07632c22ed5c7ee99b981a1e8 (patch)
tree0270e449102a910c1876acb2cf0641b9bdef68d2 /epan/ftypes/ftype-integer.c
parent46c3fe054750d1e662d48e062450cbfa6a8e1335 (diff)
Added range checking for integers and give an appropriate error
message if value is outside of range (given by field type). svn path=/trunk/; revision=39659
Diffstat (limited to 'epan/ftypes/ftype-integer.c')
-rw-r--r--epan/ftypes/ftype-integer.c233
1 files changed, 207 insertions, 26 deletions
diff --git a/epan/ftypes/ftype-integer.c b/epan/ftypes/ftype-integer.c
index cdc7085044..e2bfff2115 100644
--- a/epan/ftypes/ftype-integer.c
+++ b/epan/ftypes/ftype-integer.c
@@ -62,11 +62,21 @@ get_sinteger(fvalue_t *fv)
static gboolean
-uint_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
+uint32_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
{
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\" too small for this field, minimum 0.", s);
+ return FALSE;
+ }
+
errno = 0;
value = strtoul(s, &endptr, 0);
@@ -107,11 +117,66 @@ uint_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogF
}
static gboolean
-sint_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
+uint24_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value, LogFunc logfunc)
+{
+ gboolean valid = uint32_from_unparsed (fv, s, allow_partial_value, logfunc);
+
+ if (valid && (fv->value.uinteger > 0xFFFFFF)) { /* G_MAXUINT24 */
+ if (logfunc != NULL)
+ logfunc("\"%s\" too big for this field, maximum %u.",
+ s, 0xFFFFFF);
+ return FALSE;
+ }
+
+ return valid;
+}
+
+static gboolean
+uint16_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value, LogFunc logfunc)
+{
+ gboolean valid = uint32_from_unparsed (fv, s, allow_partial_value, logfunc);
+
+ if (valid && (fv->value.uinteger > G_MAXUINT16)) {
+ if (logfunc != NULL)
+ logfunc("\"%s\" too big for this field, maximum %u.",
+ s, G_MAXUINT16);
+ return FALSE;
+ }
+
+ return valid;
+}
+
+static gboolean
+uint8_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value, LogFunc logfunc)
+{
+ gboolean valid = uint32_from_unparsed (fv, s, allow_partial_value, logfunc);
+
+ if (valid && (fv->value.uinteger > G_MAXUINT8)) {
+ if (logfunc != NULL)
+ logfunc("\"%s\" too big for this field, maximum %u.",
+ s, G_MAXUINT8);
+ return FALSE;
+ }
+
+ return valid;
+}
+
+static gboolean
+sint32_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
{
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);
@@ -124,8 +189,10 @@ sint_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogF
if (errno == ERANGE) {
if (logfunc != NULL) {
if (value == LONG_MAX) {
- logfunc("\"%s\" causes an integer overflow.",
- s);
+ logfunc("\"%s\" causes an integer overflow.", s);
+ }
+ else if (value == LONG_MIN) {
+ logfunc("\"%s\" causes an integer underflow.", s);
}
else {
/*
@@ -160,6 +227,72 @@ sint_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogF
return TRUE;
}
+static gboolean
+sint24_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value, LogFunc logfunc)
+{
+ gboolean valid = sint32_from_unparsed (fv, s, allow_partial_value, logfunc);
+
+ if (valid) {
+ if (fv->value.sinteger > 0xFFFFFF) { /* G_MAXINT24 */
+ if (logfunc != NULL)
+ logfunc("\"%s\" too big for this field, maximum %d.",
+ s, 0xFFFFFF);
+ return FALSE;
+ } else if (fv->value.sinteger < - (0xFFFFFF + 1)) { /* G_MININT24 */
+ if (logfunc != NULL)
+ logfunc("\"%s\" too small for this field, minimum %d.",
+ s, - (0xFFFFFF + 1));
+ return FALSE;
+ }
+ }
+
+ return valid;
+}
+
+static gboolean
+sint16_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value, LogFunc logfunc)
+{
+ gboolean valid = sint32_from_unparsed (fv, s, allow_partial_value, logfunc);
+
+ if (valid) {
+ if (fv->value.sinteger > G_MAXINT16) {
+ if (logfunc != NULL)
+ logfunc("\"%s\" too big for this field, maximum %d.",
+ s, G_MAXINT16);
+ return FALSE;
+ } else if (fv->value.sinteger < G_MININT16) {
+ if (logfunc != NULL)
+ logfunc("\"%s\" too small for this field, minimum %d.",
+ s, G_MININT16);
+ return FALSE;
+ }
+ }
+
+ return valid;
+}
+
+static gboolean
+sint8_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value, LogFunc logfunc)
+{
+ gboolean valid = sint32_from_unparsed (fv, s, allow_partial_value, logfunc);
+
+ if (valid) {
+ if (fv->value.sinteger > G_MAXINT8) {
+ if (logfunc != NULL)
+ logfunc("\"%s\" too big for this field, maximum %d.",
+ s, G_MAXINT8);
+ return FALSE;
+ } else if (fv->value.sinteger < G_MININT8) {
+ if (logfunc != NULL)
+ logfunc("\"%s\" too small for this field, minimum %d.",
+ s, G_MININT8);
+ return FALSE;
+ }
+ }
+
+ return valid;
+}
+
static int
integer_repr_len(fvalue_t *fv _U_, ftrepr_t rtype _U_)
{
@@ -203,7 +336,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 (uint_from_unparsed(fv, s, TRUE, NULL)) {
+ if (uint32_from_unparsed(fv, s, TRUE, NULL)) {
return TRUE;
}
@@ -314,11 +447,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 +473,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 +486,56 @@ 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 if (value == G_MININT64) {
+ logfunc("\"%s\" causes an integer underflow.", 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 +689,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;
}
@@ -546,7 +727,7 @@ ftype_register_integers(void)
1, /* wire_size */
int_fvalue_new, /* new_value */
NULL, /* free_value */
- uint_from_unparsed, /* val_from_unparsed */
+ uint8_from_unparsed, /* val_from_unparsed */
NULL, /* val_from_string */
uinteger_to_repr, /* val_to_string_repr */
uinteger_repr_len, /* len_string_repr */
@@ -583,7 +764,7 @@ ftype_register_integers(void)
2, /* wire_size */
int_fvalue_new, /* new_value */
NULL, /* free_value */
- uint_from_unparsed, /* val_from_unparsed */
+ uint16_from_unparsed, /* val_from_unparsed */
NULL, /* val_from_string */
uinteger_to_repr, /* val_to_string_repr */
uinteger_repr_len, /* len_string_repr */
@@ -620,7 +801,7 @@ ftype_register_integers(void)
3, /* wire_size */
int_fvalue_new, /* new_value */
NULL, /* free_value */
- uint_from_unparsed, /* val_from_unparsed */
+ uint24_from_unparsed, /* val_from_unparsed */
NULL, /* val_from_string */
uinteger_to_repr, /* val_to_string_repr */
uinteger_repr_len, /* len_string_repr */
@@ -657,7 +838,7 @@ ftype_register_integers(void)
4, /* wire_size */
int_fvalue_new, /* new_value */
NULL, /* free_value */
- uint_from_unparsed, /* val_from_unparsed */
+ uint32_from_unparsed, /* val_from_unparsed */
NULL, /* val_from_string */
uinteger_to_repr, /* val_to_string_repr */
uinteger_repr_len, /* len_string_repr */
@@ -694,7 +875,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 */
@@ -731,7 +912,7 @@ ftype_register_integers(void)
1, /* wire_size */
int_fvalue_new, /* new_value */
NULL, /* free_value */
- sint_from_unparsed, /* val_from_unparsed */
+ sint8_from_unparsed, /* val_from_unparsed */
NULL, /* val_from_string */
integer_to_repr, /* val_to_string_repr */
integer_repr_len, /* len_string_repr */
@@ -768,7 +949,7 @@ ftype_register_integers(void)
2, /* wire_size */
int_fvalue_new, /* new_value */
NULL, /* free_value */
- sint_from_unparsed, /* val_from_unparsed */
+ sint16_from_unparsed, /* val_from_unparsed */
NULL, /* val_from_string */
integer_to_repr, /* val_to_string_repr */
integer_repr_len, /* len_string_repr */
@@ -805,7 +986,7 @@ ftype_register_integers(void)
3, /* wire_size */
int_fvalue_new, /* new_value */
NULL, /* free_value */
- sint_from_unparsed, /* val_from_unparsed */
+ sint24_from_unparsed, /* val_from_unparsed */
NULL, /* val_from_string */
integer_to_repr, /* val_to_string_repr */
integer_repr_len, /* len_string_repr */
@@ -842,7 +1023,7 @@ ftype_register_integers(void)
4, /* wire_size */
int_fvalue_new, /* new_value */
NULL, /* free_value */
- sint_from_unparsed, /* val_from_unparsed */
+ sint32_from_unparsed, /* val_from_unparsed */
NULL, /* val_from_string */
integer_to_repr, /* val_to_string_repr */
integer_repr_len, /* len_string_repr */
@@ -879,7 +1060,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 */
@@ -916,7 +1097,7 @@ ftype_register_integers(void)
0, /* wire_size */
boolean_fvalue_new, /* new_value */
NULL, /* free_value */
- uint_from_unparsed, /* val_from_unparsed */
+ uint32_from_unparsed, /* val_from_unparsed */
NULL, /* val_from_string */
boolean_to_repr, /* val_to_string_repr */
boolean_repr_len, /* len_string_repr */
@@ -992,7 +1173,7 @@ ftype_register_integers(void)
4, /* wire_size */
int_fvalue_new, /* new_value */
NULL, /* free_value */
- uint_from_unparsed, /* val_from_unparsed */
+ uint32_from_unparsed, /* val_from_unparsed */
NULL, /* val_from_string */
uinteger_to_repr, /* val_to_string_repr */
uinteger_repr_len, /* len_string_repr */