From 9ef70fce3c13d37527466ee67a47fa9bfd65f9fa Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Mon, 5 Sep 2016 19:05:11 -0700 Subject: 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 --- wsutil/strtoi.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 57 insertions(+), 5 deletions(-) (limited to 'wsutil') diff --git a/wsutil/strtoi.c b/wsutil/strtoi.c index 85897af026..1c7b7274a5 100644 --- a/wsutil/strtoi.c +++ b/wsutil/strtoi.c @@ -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) { \ + /* \ + * 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_MININT##bits || val > G_MAXINT##bits) { \ - *cint = 0; \ + 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; \ } \ -- cgit v1.2.1