summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--wiretap/vms.c3
-rw-r--r--wsutil/clopts_common.c5
-rw-r--r--wsutil/strtoi.c38
-rw-r--r--wsutil/strtoi.h18
4 files changed, 41 insertions, 23 deletions
diff --git a/wiretap/vms.c b/wiretap/vms.c
index 7f6a779089..9180c0e461 100644
--- a/wiretap/vms.c
+++ b/wiretap/vms.c
@@ -328,6 +328,7 @@ parse_vms_packet(FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf, int *err, gch
struct tm tm;
char mon[4] = {'J', 'A', 'N', 0};
gchar *p;
+ const gchar *endp;
static const gchar months[] = "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC";
guint32 i;
int offset = 0;
@@ -388,7 +389,7 @@ parse_vms_packet(FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf, int *err, gch
return FALSE;
}
- if (!ws_strtou32(p, &pkt_len)) {
+ if (!ws_strtou32(p, &endp, &pkt_len) || (*endp != '\0' && !g_ascii_isspace(*endp))) {
*err = WTAP_ERR_BAD_FILE;
*err_info = g_strdup_printf("vms: Length field '%s' not valid", p);
return FALSE;
diff --git a/wsutil/clopts_common.c b/wsutil/clopts_common.c
index 695559eb02..1967014c82 100644
--- a/wsutil/clopts_common.c
+++ b/wsutil/clopts_common.c
@@ -33,10 +33,11 @@
int
get_natural_int(const char *string, const char *name)
{
+ const char *end;
gint32 number;
- if (!ws_strtoi32(string, &number)) {
- if (errno == EINVAL) {
+ if (!ws_strtoi32(string, &end, &number)) {
+ if (errno == EINVAL || *end != '\0') {
cmdarg_err("The specified %s \"%s\" isn't a decimal number", name, string);
exit(1);
}
diff --git a/wsutil/strtoi.c b/wsutil/strtoi.c
index 96683d9d43..26e756d444 100644
--- a/wsutil/strtoi.c
+++ b/wsutil/strtoi.c
@@ -27,15 +27,17 @@
#include "strtoi.h"
#include <errno.h>
-gboolean ws_strtoi64(const gchar* str, gint64* cint)
+gboolean ws_strtoi64(const gchar* str, const gchar** endptr, gint64* cint)
{
- gchar* endptr;
+ gchar* end;
gint64 val;
errno = 0;
- val = g_ascii_strtoll(str, &endptr, 10);
- if ((val == 0 && endptr == str) || (*endptr != 0)) {
+ val = g_ascii_strtoll(str, &end, 10);
+ if (val == 0 && end == str) {
*cint = 0;
+ if (endptr != NULL)
+ *endptr = end;
errno = EINVAL;
return FALSE;
}
@@ -45,16 +47,20 @@ gboolean ws_strtoi64(const gchar* str, gint64* cint)
* report the value as "too small" or "too large".
*/
*cint = val;
+ if (endptr != NULL)
+ *endptr = end;
/* errno is already set */
return FALSE;
}
+ if (endptr != NULL)
+ *endptr = end;
*cint = val;
return TRUE;
}
-gboolean ws_strtou64(const gchar* str, guint64* cint)
+gboolean ws_strtou64(const gchar* str, const gchar** endptr, guint64* cint)
{
- gchar* endptr;
+ gchar* end;
guint64 val;
if (str[0] == '-' || str[0] == '+') {
@@ -62,13 +68,17 @@ gboolean ws_strtou64(const gchar* str, guint64* cint)
* Unsigned numbers don't have a sign.
*/
*cint = 0;
+ if (endptr != NULL)
+ *endptr = str;
errno = EINVAL;
return FALSE;
}
errno = 0;
- val = g_ascii_strtoull(str, &endptr, 10);
- if ((val == 0 && endptr == str) || (*endptr != 0)) {
+ val = g_ascii_strtoull(str, &end, 10);
+ if (val == 0 && end == str) {
*cint = 0;
+ if (endptr != NULL)
+ *endptr = end;
errno = EINVAL;
return FALSE;
}
@@ -77,18 +87,22 @@ gboolean ws_strtou64(const gchar* str, guint64* cint)
* Return the value, because ws_strtoi64() does.
*/
*cint = val;
+ if (endptr != NULL)
+ *endptr = end;
/* errno is already set */
return FALSE;
}
+ if (endptr != NULL)
+ *endptr = end;
*cint = val;
return TRUE;
}
#define DEFINE_WS_STRTOI_BITS(bits) \
-gboolean ws_strtoi##bits(const gchar* str, gint##bits* cint) \
+gboolean ws_strtoi##bits(const gchar* str, const gchar** endptr, gint##bits* cint) \
{ \
gint64 val; \
- if (!ws_strtoi64(str, &val)) { \
+ if (!ws_strtoi64(str, endptr, &val)) { \
/* \
* For ERANGE, return either G_MININT##bits or \
* G_MAXINT##bits so our caller knows whether \
@@ -134,10 +148,10 @@ DEFINE_WS_STRTOI_BITS(16)
DEFINE_WS_STRTOI_BITS(8)
#define DEFINE_WS_STRTOU_BITS(bits) \
-int ws_strtou##bits(const gchar* str, guint##bits* cint) \
+int ws_strtou##bits(const gchar* str, const gchar** endptr, guint##bits* cint) \
{ \
guint64 val; \
- if (!ws_strtou64(str, &val)) { \
+ if (!ws_strtou64(str, endptr, &val)) { \
/* \
* For ERANGE, return G_MAXUINT##bits for parallelism \
* with ws_strtoi##bits(). \
diff --git a/wsutil/strtoi.h b/wsutil/strtoi.h
index 3b35bfc323..ed48b52aac 100644
--- a/wsutil/strtoi.h
+++ b/wsutil/strtoi.h
@@ -32,20 +32,22 @@
/*
* \brief Convert a string to a signed/unsigned int, with error checks.
* \param str The string to convert
+ * \param endptr NULL or pointer to a pointer set to point to the
+ * character after the last character of the number
* \param cint The converted integer
* \return TRUE if the conversion suceeds, 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_strtoi64(const gchar* str, gint64* cint);
-WS_DLL_PUBLIC gboolean ws_strtoi32(const gchar* str, gint32* cint);
-WS_DLL_PUBLIC gboolean ws_strtoi16(const gchar* str, gint16* cint);
-WS_DLL_PUBLIC gboolean ws_strtoi8 (const gchar* str, gint8* cint);
+WS_DLL_PUBLIC gboolean ws_strtoi64(const gchar* str, const gchar** endptr, gint64* 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_strtoi8 (const gchar* str, const gchar** endptr, gint8* cint);
-WS_DLL_PUBLIC gboolean ws_strtou64(const gchar* str, guint64* cint);
-WS_DLL_PUBLIC gboolean ws_strtou32(const gchar* str, guint32* cint);
-WS_DLL_PUBLIC gboolean ws_strtou16(const gchar* str, guint16* cint);
-WS_DLL_PUBLIC gboolean ws_strtou8 (const gchar* str, guint8* 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);
#endif