aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2004-07-16 23:35:46 +0000
committerGuy Harris <guy@alum.mit.edu>2004-07-16 23:35:46 +0000
commitc27d80c9adce0ba21254a63ff644e45d982c87e5 (patch)
tree94dd014692ef7747c5785d24d581e9da63192f8a
parent1715f98d9c515ce36168e8642e9d561c38b88a22 (diff)
I'm not sure "strtol()" and "strtoul()" are guaranteed to clear "errno"
on success, so we clear it before calling them. Assign the value of "strtol()" to a "long" and assign the value of "strtoul()" to an "unsigned long", as those are the return types for those functions - "gint32" and "guint32" might not be large enough for the return value on an LP64 platform. Check for errno being EINVAL, as that can happen if the number isn't valid. Before assigning the value returned by "strtol()" or "strtoul()" to the final destination, check whether it's in the right range for that destination. svn path=/trunk/; revision=11382
-rw-r--r--epan/dfilter/scanner.l25
-rw-r--r--epan/ftypes/ftype-integer.c22
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;
}