Use ws_basetostru32(), rather than strtoul(), when parsing ranges.

Make ws_basetostru32(), and the other ws_baseto... routines, public, and
use ws_basetostru32() when parsing ranges, to detect additional errors
such as negative values.

Addresses part of
https://ask.wireshark.org/question/5538/preference-range/.

Change-Id: I00fac97a198a237b01b5cd9406ea32c220f80972
Reviewed-on: https://code.wireshark.org/review/30266
Reviewed-by: Guy Harris <guy@alum.mit.edu>
This commit is contained in:
Guy Harris 2018-10-19 13:28:05 -07:00
parent 075ef8029c
commit 5e019c6b8f
3 changed files with 33 additions and 9 deletions

View File

@ -13,6 +13,7 @@
#include "config.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
@ -22,7 +23,8 @@
#include <epan/frame_data.h>
#include <epan/range.h>
#include <stdio.h>
#include <wsutil/strtoi.h>
/*
* Size of the header of a range_t.
@ -84,11 +86,11 @@ range_convert_str_work(wmem_allocator_t *scope, range_t **rangep, const gchar *e
range_t *range;
guint nranges;
const gchar *p;
char *endp;
const char *endp;
gchar c;
guint i;
guint32 tmp;
unsigned long val;
guint32 val;
if ( (rangep == NULL) || (es == NULL) )
return CVT_SYNTAX_ERROR;
@ -135,8 +137,8 @@ range_convert_str_work(wmem_allocator_t *scope, range_t **rangep, const gchar *e
} else if (g_ascii_isdigit(c)) {
/* Subrange starts with the specified number */
errno = 0;
val = strtoul(p, &endp, 0);
if (p == endp) {
ws_basestrtou32(p, &endp, &val, 0);
if (errno == EINVAL) {
/* That wasn't a valid number. */
wmem_free(scope, range);
return CVT_SYNTAX_ERROR;
@ -181,8 +183,8 @@ range_convert_str_work(wmem_allocator_t *scope, range_t **rangep, const gchar *e
} else if (g_ascii_isdigit(c)) {
/* Subrange ends with the specified number. */
errno = 0;
val = strtoul(p, &endp, 0);
if (p == endp) {
ws_basestrtou32(p, &endp, &val, 0);
if (errno == EINVAL) {
/* That wasn't a valid number. */
wmem_free(scope, range);
return CVT_SYNTAX_ERROR;

View File

@ -102,7 +102,7 @@ DEFINE_WS_STRTOI_BITS(32)
DEFINE_WS_STRTOI_BITS(16)
DEFINE_WS_STRTOI_BITS(8)
static 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;
guint64 val;
@ -160,7 +160,7 @@ gboolean ws_hexstrtou64(const gchar* str, const gchar** endptr, guint64* cint)
}
#define DEFINE_WS_STRTOU_BITS(bits) \
static gboolean ws_basestrtou##bits(const gchar* str, const gchar** endptr, guint##bits* cint, int base) \
gboolean ws_basestrtou##bits(const gchar* str, const gchar** endptr, guint##bits* cint, int base) \
{ \
guint64 val; \
if (!ws_basestrtou64(str, endptr, &val, base)) { \

View File

@ -61,6 +61,28 @@ WS_DLL_PUBLIC gboolean ws_hexstrtou32(const gchar* str, const gchar** endptr, gu
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);
/*
* \brief Convert a string in the specified base to an unsigned int, with
* error checks.
* \param str The string to convert
* \param endptr A pointer that will store a pointer to the first invalid
* character in str, allowing a number to be parsed even if there is trailing
* whitespace. If NULL, then the string is assumed to contain only valid
* characters (or it will error out).
* \param cint The converted integer
* \param base The base for the integer; 0 means "if it begins with 0x,
* it's hex, otherwise if it begins with 0, it's octal, otherwise it's
* decimal".
* \return TRUE if the conversion succeeds, FALSE otherwise.
* On error, errno is set to EINVAL for unrecognized input and ERANGE
* if the resulting number does not fit in the type.
*/
WS_DLL_PUBLIC gboolean ws_basestrtou64(const gchar* str, const gchar** endptr, guint64* 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_basestrtou8 (const gchar* str, const gchar** endptr, guint8* cint, int base);
#ifdef __cplusplus
}
#endif /* __cplusplus */