Add ws_hexstrtou{bits} and use ws_hexstrtou32 in androiddump.

Make the reply length unsigned - there's no reason for it to be signed.

Change-Id: I5f4d1f027eeddee939547c052220efb89800f4b1
Reviewed-on: https://code.wireshark.org/review/17740
Reviewed-by: Guy Harris <guy@alum.mit.edu>
This commit is contained in:
Guy Harris 2016-09-16 10:41:11 -07:00
parent 1ca260bbb4
commit 770a8737d7
3 changed files with 88 additions and 46 deletions

View File

@ -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) {

View File

@ -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)

View File

@ -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
/*