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_basestrtou64@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_assure_space@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_hexstrtou64@Base 2.3.0
ws_hexstrtou8@Base 2.3.0
ws_hexstrtou@Base 3.3.0
ws_hmac_buffer@Base 2.3.0
ws_inet_ntop4@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_strtoi64@Base 2.3.0
ws_strtoi8@Base 2.3.0
ws_strtoi@Base 3.3.0
ws_strtou16@Base 2.3.0
ws_strtou32@Base 2.3.0
ws_strtou64@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_vadd_crash_info@Base 2.5.2
ws_xton@Base 1.12.0~rc1

View File

@ -24,6 +24,7 @@
#include "ui/capture_globals.h"
#include "wiretap/wtap.h"
#include "epan/to_str.h"
#include "wsutil/strtoi.h"
/*
* 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
capture_dev_get_if_int_property(const gchar *pref, const gchar *if_name)
{
gchar *property_string, *next;
long property;
gchar *property_string;
gint property;
property_string = capture_dev_get_if_property(pref, if_name);
if (property_string == NULL) {
/* No property found for this interface. */
return -1;
}
property = strtol(property_string, &next, 10);
if (next == property_string || *next != '\0' || property < 0) {
/* Syntax error */
g_free(property_string);
return -1;
}
if (property > G_MAXINT) {
/* Value doesn't fit in a gint */
if (!ws_strtoi(property_string, NULL, &property)) {
/* Syntax error or range error */
g_free(property_string);
return -1;
}
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);
for (i = 0; if_tokens[i] != NULL; i++) {
gchar *colonp, *next;
long value;
gchar *colonp;
const gchar *next;
gint value;
/*
* 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. */
break;
}
value = strtol(colonp + 3, &next, 10);
if (next == colonp + 3 || *next != ')' || value < 0) {
/* Syntax error. Give up. */
break;
}
if (value > G_MAXINT) {
/* Value doesn't fit in a gint. Give up. */
if (!ws_strtoi(colonp + 3, &next, &value) ||
next == colonp + 3 || *next != ')' || value < 0) {
/* Syntax error or range error. Give up. */
break;
}
found = TRUE;
*hassnap = TRUE;
*snaplen = (gint)value;
*snaplen = value;
} else {
/* Bad {hassnap}. Give up. */
break;

View File

@ -102,6 +102,50 @@ DEFINE_WS_STRTOI_BITS(32)
DEFINE_WS_STRTOI_BITS(16)
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)
{
gchar* end;
@ -204,6 +248,46 @@ DEFINE_WS_STRTOU_BITS(32)
DEFINE_WS_STRTOU_BITS(16)
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
*

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_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_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_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_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.
@ -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_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_hexstrtou (const gchar* str, const gchar** endptr, guint* cint);
/*
* \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_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_basestrtou (const gchar* str, const gchar** endptr, guint* cint, int base);
#ifdef __cplusplus
}