diff --git a/extcap/androiddump.c b/extcap/androiddump.c index b92c1705fc..031325294e 100644 --- a/extcap/androiddump.c +++ b/extcap/androiddump.c @@ -439,7 +439,7 @@ static socket_handle_t adb_connect(const char *server_ip, unsigned short *server static char *adb_send_and_receive(socket_handle_t sock, const char *adb_service, char *buffer, int buffer_length, gssize *data_length) { gssize used_buffer_length; - gint32 length; + guint32 length; gssize result; char status[4]; char tmp_buffer; @@ -471,7 +471,11 @@ static char *adb_send_and_receive(socket_handle_t sock, const char *adb_service, memcpy(status, buffer, 4); tmp_buffer = buffer[8]; buffer[8] = '\0'; - length = (gssize) g_ascii_strtoll(buffer + 4, NULL, 16); + if (!ws_hexstrtou32(buffer + 4, NULL, &length)) { + g_warning("Invalid reply length <%s> while reading reply for <%s>", buffer + 4, adb_service); + + return NULL; + } buffer[8] = tmp_buffer; while (used_buffer_length < length + 8) { diff --git a/wsutil/strtoi.c b/wsutil/strtoi.c index 75d0cf3ff4..c855466d43 100644 --- a/wsutil/strtoi.c +++ b/wsutil/strtoi.c @@ -58,46 +58,6 @@ gboolean ws_strtoi64(const gchar* str, const gchar** endptr, gint64* cint) return TRUE; } -gboolean ws_strtou64(const gchar* str, const gchar** endptr, guint64* cint) -{ - gchar* end; - guint64 val; - - if (str[0] == '-' || str[0] == '+') { - /* - * 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, &end, 10); - if ((val == 0 && end == str) || (endptr == NULL && *end != '\0')) { - *cint = 0; - if (endptr != NULL) - *endptr = end; - errno = EINVAL; - return FALSE; - } - if (val == G_MAXUINT64 && errno == ERANGE) { - /* - * 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, const gchar** endptr, gint##bits* cint) \ { \ @@ -147,17 +107,67 @@ 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) +{ + gchar* end; + guint64 val; + + if (str[0] == '-' || str[0] == '+') { + /* + * 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, &end, base); + if ((val == 0 && end == str) || (endptr == NULL && *end != '\0')) { + *cint = 0; + if (endptr != NULL) + *endptr = end; + errno = EINVAL; + return FALSE; + } + if (val == G_MAXUINT64 && errno == ERANGE) { + /* + * 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; +} + +gboolean ws_strtou64(const gchar* str, const gchar** endptr, guint64* cint) +{ + return ws_basestrtou64(str, endptr, cint, 10); +} + +gboolean ws_hexstrtou64(const gchar* str, const gchar** endptr, guint64* cint) +{ + return ws_basestrtou64(str, endptr, cint, 16); +} + #define DEFINE_WS_STRTOU_BITS(bits) \ -int ws_strtou##bits(const gchar* str, const gchar** endptr, guint##bits* cint) \ +static gboolean ws_basestrtou##bits(const gchar* str, const gchar** endptr, guint##bits* cint, int base) \ { \ guint64 val; \ - if (!ws_strtou64(str, endptr, &val)) { \ + if (!ws_basestrtou64(str, endptr, &val, base)) { \ /* \ * For ERANGE, return G_MAXUINT##bits for parallelism \ * with ws_strtoi##bits(). \ * \ * For other errors, return 0, for parallelism \ - * with ws_strtou64(). \ + * with ws_basestrtou64(). \ */ \ if (errno == ERANGE) \ *cint = G_MAXUINT##bits; \ @@ -176,6 +186,16 @@ int ws_strtou##bits(const gchar* str, const gchar** endptr, guint##bits* cint) \ } \ *cint = (guint##bits)val; \ return TRUE; \ +} \ +\ +gboolean ws_strtou##bits(const gchar* str, const gchar** endptr, guint##bits* cint) \ +{ \ + return ws_basestrtou##bits(str, endptr, cint, 10); \ +} \ +\ +gboolean ws_hexstrtou##bits(const gchar* str, const gchar** endptr, guint##bits* cint) \ +{ \ + return ws_basestrtou##bits(str, endptr, cint, 16); \ } DEFINE_WS_STRTOU_BITS(32) diff --git a/wsutil/strtoi.h b/wsutil/strtoi.h index 3361da8fc3..eb65fec218 100644 --- a/wsutil/strtoi.h +++ b/wsutil/strtoi.h @@ -30,7 +30,7 @@ #include "ws_symbol_export.h" /* - * \brief Convert a string to a signed/unsigned int, with error checks. + * \brief Convert a decimal string to a signed/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 @@ -51,6 +51,24 @@ WS_DLL_PUBLIC gboolean ws_strtou32(const gchar* str, const gchar** endptr, guint 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); +/* + * \brief Convert a hexadecimal string 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 + * \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_hexstrtou64(const gchar* str, const gchar** endptr, guint64* 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_hexstrtou8 (const gchar* str, const gchar** endptr, guint8* cint); + #endif /*