Add ws_strtoi() and ws_strtoui() routines and use them.

Those fetch gint and guint values, respectively, rather than values with
specified sizes in bits.

This should squelch Coverity CID 1457357.

Change-Id: Ia8f100bd3fe90c266e24a4346f80b2667c653b93
Reviewed-on: https://code.wireshark.org/review/36177
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot
Reviewed-by: Guy Harris <guy@alum.mit.edu>
This commit is contained in:
Guy Harris 2020-02-24 23:36:35 -08:00
parent f2a64e9559
commit cd6134da90
4 changed files with 105 additions and 21 deletions

View File

@ -194,6 +194,7 @@ libwsutil.so.0 libwsutil0 #MINVER#
ws_basestrtou32@Base 2.9.0 ws_basestrtou32@Base 2.9.0
ws_basestrtou64@Base 2.9.0 ws_basestrtou64@Base 2.9.0
ws_basestrtou8@Base 2.9.0 ws_basestrtou8@Base 2.9.0
ws_basestrtou@Base 3.3.0
ws_buffer_append@Base 1.99.0 ws_buffer_append@Base 1.99.0
ws_buffer_assure_space@Base 1.99.0 ws_buffer_assure_space@Base 1.99.0
ws_buffer_free@Base 1.99.0 ws_buffer_free@Base 1.99.0
@ -206,6 +207,7 @@ libwsutil.so.0 libwsutil0 #MINVER#
ws_hexstrtou32@Base 2.3.0 ws_hexstrtou32@Base 2.3.0
ws_hexstrtou64@Base 2.3.0 ws_hexstrtou64@Base 2.3.0
ws_hexstrtou8@Base 2.3.0 ws_hexstrtou8@Base 2.3.0
ws_hexstrtou@Base 3.3.0
ws_hmac_buffer@Base 2.3.0 ws_hmac_buffer@Base 2.3.0
ws_inet_ntop4@Base 2.1.2 ws_inet_ntop4@Base 2.1.2
ws_inet_ntop6@Base 2.1.2 ws_inet_ntop6@Base 2.1.2
@ -225,10 +227,12 @@ libwsutil.so.0 libwsutil0 #MINVER#
ws_strtoi32@Base 2.3.0 ws_strtoi32@Base 2.3.0
ws_strtoi64@Base 2.3.0 ws_strtoi64@Base 2.3.0
ws_strtoi8@Base 2.3.0 ws_strtoi8@Base 2.3.0
ws_strtoi@Base 3.3.0
ws_strtou16@Base 2.3.0 ws_strtou16@Base 2.3.0
ws_strtou32@Base 2.3.0 ws_strtou32@Base 2.3.0
ws_strtou64@Base 2.3.0 ws_strtou64@Base 2.3.0
ws_strtou8@Base 2.3.0 ws_strtou8@Base 2.3.0
ws_strtou@Base 3.3.0
ws_utf8_char_len@Base 1.12.0~rc1 ws_utf8_char_len@Base 1.12.0~rc1
ws_vadd_crash_info@Base 2.5.2 ws_vadd_crash_info@Base 2.5.2
ws_xton@Base 1.12.0~rc1 ws_xton@Base 1.12.0~rc1

View File

@ -24,6 +24,7 @@
#include "ui/capture_globals.h" #include "ui/capture_globals.h"
#include "wiretap/wtap.h" #include "wiretap/wtap.h"
#include "epan/to_str.h" #include "epan/to_str.h"
#include "wsutil/strtoi.h"
/* /*
* In a list of interface information, in the form of a comma-separated * In a list of interface information, in the form of a comma-separated
@ -93,28 +94,22 @@ capture_dev_get_if_property(const gchar *pref, const gchar *if_name)
static gint static gint
capture_dev_get_if_int_property(const gchar *pref, const gchar *if_name) capture_dev_get_if_int_property(const gchar *pref, const gchar *if_name)
{ {
gchar *property_string, *next; gchar *property_string;
long property; gint property;
property_string = capture_dev_get_if_property(pref, if_name); property_string = capture_dev_get_if_property(pref, if_name);
if (property_string == NULL) { if (property_string == NULL) {
/* No property found for this interface. */ /* No property found for this interface. */
return -1; return -1;
} }
property = strtol(property_string, &next, 10); if (!ws_strtoi(property_string, NULL, &property)) {
if (next == property_string || *next != '\0' || property < 0) { /* Syntax error or range error */
/* Syntax error */
g_free(property_string);
return -1;
}
if (property > G_MAXINT) {
/* Value doesn't fit in a gint */
g_free(property_string); g_free(property_string);
return -1; return -1;
} }
g_free(property_string); g_free(property_string);
return (gint)property; return property;
} }
/* /*
@ -165,8 +160,9 @@ capture_dev_user_snaplen_find(const gchar *if_name, gboolean *hassnap, int *snap
*/ */
if_tokens = g_strsplit(prefs.capture_devices_snaplen, ",", -1); if_tokens = g_strsplit(prefs.capture_devices_snaplen, ",", -1);
for (i = 0; if_tokens[i] != NULL; i++) { for (i = 0; if_tokens[i] != NULL; i++) {
gchar *colonp, *next; gchar *colonp;
long value; const gchar *next;
gint value;
/* /*
* This one's a bit ugly. * This one's a bit ugly.
@ -200,18 +196,14 @@ capture_dev_user_snaplen_find(const gchar *if_name, gboolean *hassnap, int *snap
/* Not followed by a parenthesis. Give up. */ /* Not followed by a parenthesis. Give up. */
break; break;
} }
value = strtol(colonp + 3, &next, 10); if (!ws_strtoi(colonp + 3, &next, &value) ||
if (next == colonp + 3 || *next != ')' || value < 0) { next == colonp + 3 || *next != ')' || value < 0) {
/* Syntax error. Give up. */ /* Syntax error or range error. Give up. */
break;
}
if (value > G_MAXINT) {
/* Value doesn't fit in a gint. Give up. */
break; break;
} }
found = TRUE; found = TRUE;
*hassnap = TRUE; *hassnap = TRUE;
*snaplen = (gint)value; *snaplen = value;
} else { } else {
/* Bad {hassnap}. Give up. */ /* Bad {hassnap}. Give up. */
break; break;

View File

@ -102,6 +102,50 @@ DEFINE_WS_STRTOI_BITS(32)
DEFINE_WS_STRTOI_BITS(16) DEFINE_WS_STRTOI_BITS(16)
DEFINE_WS_STRTOI_BITS(8) DEFINE_WS_STRTOI_BITS(8)
gboolean ws_strtoi(const gchar* str, const gchar** endptr, gint* cint)
{
gint64 val = 0;
if (!ws_strtoi64(str, endptr, &val)) {
/*
* For ERANGE, return either G_MININT or
* G_MAXINT 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;
else
*cint = G_MAXINT;
} else
*cint = 0;
return FALSE;
}
if (val < G_MININT) {
/*
* Return G_MININT so our caller knows whether to
* report the value as "too small" or "too large".
*/
*cint = G_MININT;
errno = ERANGE;
return FALSE;
}
if (val > G_MAXINT) {
/*
* Return G_MAXINT so our caller knows whether to
* report the value as "too small" or "too large".
*/
*cint = G_MAXINT;
errno = ERANGE;
return FALSE;
}
*cint = (gint)val;
return TRUE;
}
gboolean ws_basestrtou64(const gchar* str, const gchar** endptr, guint64* cint, int base) gboolean ws_basestrtou64(const gchar* str, const gchar** endptr, guint64* cint, int base)
{ {
gchar* end; gchar* end;
@ -204,6 +248,46 @@ DEFINE_WS_STRTOU_BITS(32)
DEFINE_WS_STRTOU_BITS(16) DEFINE_WS_STRTOU_BITS(16)
DEFINE_WS_STRTOU_BITS(8) DEFINE_WS_STRTOU_BITS(8)
gboolean ws_basestrtou(const gchar* str, const gchar** endptr, guint* cint, int base)
{
guint64 val;
if (!ws_basestrtou64(str, endptr, &val, base)) {
/*
* For ERANGE, return G_MAXUINT for parallelism
* with ws_strtoi().
*
* For other errors, return 0, for parallelism
* with ws_basestrtou64().
*/
if (errno == ERANGE)
*cint = G_MAXUINT;
else
*cint = 0;
return FALSE;
}
if (val > G_MAXUINT) {
/*
* Return G_MAXUINT for parallelism with
* ws_strtoi().
*/
*cint = G_MAXUINT;
errno = ERANGE;
return FALSE;
}
*cint = (guint)val;
return TRUE;
}
gboolean ws_strtou(const gchar* str, const gchar** endptr, guint* cint)
{
return ws_basestrtou(str, endptr, cint, 10);
}
\
gboolean ws_hexstrtou(const gchar* str, const gchar** endptr, guint* cint)
{
return ws_basestrtou(str, endptr, cint, 16);
}
/* /*
* Editor modelines - https://www.wireshark.org/tools/modelines.html * Editor modelines - https://www.wireshark.org/tools/modelines.html
* *

View File

@ -37,11 +37,13 @@ WS_DLL_PUBLIC gboolean ws_strtoi64(const gchar* str, const gchar** endptr, gint6
WS_DLL_PUBLIC gboolean ws_strtoi32(const gchar* str, const gchar** endptr, gint32* cint); WS_DLL_PUBLIC gboolean ws_strtoi32(const gchar* str, const gchar** endptr, gint32* cint);
WS_DLL_PUBLIC gboolean ws_strtoi16(const gchar* str, const gchar** endptr, gint16* cint); WS_DLL_PUBLIC gboolean ws_strtoi16(const gchar* str, const gchar** endptr, gint16* cint);
WS_DLL_PUBLIC gboolean ws_strtoi8 (const gchar* str, const gchar** endptr, gint8* cint); WS_DLL_PUBLIC gboolean ws_strtoi8 (const gchar* str, const gchar** endptr, gint8* cint);
WS_DLL_PUBLIC gboolean ws_strtoi (const gchar* str, const gchar** endptr, gint* cint);
WS_DLL_PUBLIC gboolean ws_strtou64(const gchar* str, const gchar** endptr, guint64* cint); WS_DLL_PUBLIC gboolean ws_strtou64(const gchar* str, const gchar** endptr, guint64* cint);
WS_DLL_PUBLIC gboolean ws_strtou32(const gchar* str, const gchar** endptr, guint32* cint); WS_DLL_PUBLIC gboolean ws_strtou32(const gchar* str, const gchar** endptr, guint32* cint);
WS_DLL_PUBLIC gboolean ws_strtou16(const gchar* str, const gchar** endptr, guint16* cint); WS_DLL_PUBLIC gboolean ws_strtou16(const gchar* str, const gchar** endptr, guint16* cint);
WS_DLL_PUBLIC gboolean ws_strtou8 (const gchar* str, const gchar** endptr, guint8* cint); WS_DLL_PUBLIC gboolean ws_strtou8 (const gchar* str, const gchar** endptr, guint8* cint);
WS_DLL_PUBLIC gboolean ws_strtou (const gchar* str, const gchar** endptr, guint* cint);
/* /*
* \brief Convert a hexadecimal string to an unsigned int, with error checks. * \brief Convert a hexadecimal string to an unsigned int, with error checks.
@ -60,6 +62,7 @@ WS_DLL_PUBLIC gboolean ws_hexstrtou64(const gchar* str, const gchar** endptr, gu
WS_DLL_PUBLIC gboolean ws_hexstrtou32(const gchar* str, const gchar** endptr, guint32* cint); WS_DLL_PUBLIC gboolean ws_hexstrtou32(const gchar* str, const gchar** endptr, guint32* cint);
WS_DLL_PUBLIC gboolean ws_hexstrtou16(const gchar* str, const gchar** endptr, guint16* cint); WS_DLL_PUBLIC gboolean ws_hexstrtou16(const gchar* str, const gchar** endptr, guint16* cint);
WS_DLL_PUBLIC gboolean ws_hexstrtou8 (const gchar* str, const gchar** endptr, guint8* cint); WS_DLL_PUBLIC gboolean ws_hexstrtou8 (const gchar* str, const gchar** endptr, guint8* cint);
WS_DLL_PUBLIC gboolean ws_hexstrtou (const gchar* str, const gchar** endptr, guint* cint);
/* /*
* \brief Convert a string in the specified base to an unsigned int, with * \brief Convert a string in the specified base to an unsigned int, with
@ -82,6 +85,7 @@ WS_DLL_PUBLIC gboolean ws_basestrtou64(const gchar* str, const gchar** endptr, g
WS_DLL_PUBLIC gboolean ws_basestrtou32(const gchar* str, const gchar** endptr, guint32* cint, int base); WS_DLL_PUBLIC gboolean ws_basestrtou32(const gchar* str, const gchar** endptr, guint32* cint, int base);
WS_DLL_PUBLIC gboolean ws_basestrtou16(const gchar* str, const gchar** endptr, guint16* cint, int base); WS_DLL_PUBLIC gboolean ws_basestrtou16(const gchar* str, const gchar** endptr, guint16* cint, int base);
WS_DLL_PUBLIC gboolean ws_basestrtou8 (const gchar* str, const gchar** endptr, guint8* cint, int base); WS_DLL_PUBLIC gboolean ws_basestrtou8 (const gchar* str, const gchar** endptr, guint8* cint, int base);
WS_DLL_PUBLIC gboolean ws_basestrtou (const gchar* str, const gchar** endptr, guint* cint, int base);
#ifdef __cplusplus #ifdef __cplusplus
} }