Return the maximum or minimum value for ERANGE.

That way, for signed values, the caller knows whether ERANGE means "too
large" or "too small"; this is analogous to what the C routines return.

Change-Id: Ifc1fc4723733be606487093f8aa77ae2d89d2c40
Reviewed-on: https://code.wireshark.org/review/17512
Reviewed-by: Guy Harris <guy@alum.mit.edu>
This commit is contained in:
Guy Harris 2016-09-05 19:05:11 -07:00
parent 97103d40e3
commit 9ef70fce3c
1 changed files with 57 additions and 5 deletions

View File

@ -40,7 +40,11 @@ gboolean ws_strtoi64(const gchar* str, gint64* cint)
return FALSE;
}
if ((val == G_MAXINT64 || val == G_MININT64) && errno == ERANGE) {
*cint = 0;
/*
* Return the value, so our caller knows whether to
* report the value as "too small" or "too large".
*/
*cint = val;
/* errno is already set */
return FALSE;
}
@ -68,7 +72,11 @@ gboolean ws_strtou64(const gchar* str, guint64* cint)
return FALSE;
}
if (val == G_MAXUINT64 && errno == ERANGE) {
*cint = 0;
/*
* Return the value, because ws_strtoi64() does.
*/
*cint = val;
/* errno is already set */
return FALSE;
}
*cint = val;
@ -80,10 +88,39 @@ gboolean ws_strtoi##bits(const gchar* str, gint##bits* cint) \
{ \
gint64 val; \
if (!ws_strtoi64(str, &val)) { \
/* \
* For ERANGE, return either G_MININT##bits or \
* G_MAXINT##bits so our caller knows whether \
* to report the value as "too small" or "too \
* large". \
* \
* For other errors, return 0, for parallelism \
* with ws_strtoi64(). \
*/ \
if (errno == ERANGE) { \
if (val < 0) \
*cint = G_MININT##bits; \
else \
*cint = G_MAXINT##bits; \
} else \
*cint = 0; \
return FALSE; \
} \
if (val < G_MININT##bits || val > G_MAXINT##bits) { \
*cint = 0; \
if (val < G_MININT##bits) { \
/* \
* Return G_MININT##bits so our caller knows whether to \
* report the value as "too small" or "too large". \
*/ \
*cint = G_MININT##bits; \
errno = ERANGE; \
return FALSE; \
} \
if (val > G_MAXINT##bits) { \
/* \
* Return G_MAXINT##bits so our caller knows whether to \
* report the value as "too small" or "too large". \
*/ \
*cint = G_MAXINT##bits; \
errno = ERANGE; \
return FALSE; \
} \
@ -100,10 +137,25 @@ int ws_strtou##bits(const gchar* str, guint##bits* cint) \
{ \
guint64 val; \
if (!ws_strtou64(str, &val)) { \
/* \
* For ERANGE, return G_MAXUINT##bits for parallelism \
* with ws_strtoi##bits(). \
* \
* For other errors, return 0, for parallelism \
* with ws_strtou64(). \
*/ \
if (errno == ERANGE) \
*cint = G_MAXUINT##bits; \
else \
*cint = 0; \
return FALSE; \
} \
if (val > G_MAXUINT##bits) { \
*cint = 0; \
/* \
* Return G_MAXUINT##bits for parallelism with \
* ws_strtoi##bits(). \
*/ \
*cint = G_MAXUINT##bits; \
errno = ERANGE; \
return FALSE; \
} \