From c3bd5c9d9167acff2d8230c72e446e4a94e05cd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Valverde?= Date: Sun, 25 Jul 2021 22:53:03 +0100 Subject: [PATCH] Move bytes_to_str() to wsutil This utility function is useful outside of epan. Move it to wsutil and export the interface. The move isn't completely clean as it requires duplicating two small inline functions but that was necessary to avoiding moving too much at once. --- debian/libwireshark0.symbols | 3 - debian/libwsutil0.symbols | 4 + epan/ftypes/ftype-protocol.c | 2 +- epan/to_str-int.h | 12 --- epan/to_str.c | 116 --------------------- epan/to_str.h | 34 +------ wsutil/CMakeLists.txt | 2 + wsutil/to_str.c | 188 +++++++++++++++++++++++++++++++++++ wsutil/to_str.h | 72 ++++++++++++++ 9 files changed, 268 insertions(+), 165 deletions(-) create mode 100644 wsutil/to_str.c create mode 100644 wsutil/to_str.h diff --git a/debian/libwireshark0.symbols b/debian/libwireshark0.symbols index bb44b75d22..de3ed614a5 100644 --- a/debian/libwireshark0.symbols +++ b/debian/libwireshark0.symbols @@ -75,11 +75,8 @@ libwireshark.so.0 libwireshark0 #MINVER# build_column_format_array@Base 1.9.1 byte_array_dup@Base 1.9.1 byte_array_equal@Base 1.9.1 - bytes_to_hexstr@Base 2.1.0 - bytes_to_str@Base 1.99.2 bytesprefix_to_str@Base 2.3.0 bytesval_to_str@Base 2.3.0 - bytestring_to_str@Base 1.9.1 call_ber_oid_callback@Base 1.9.1 call_capture_dissector@Base 2.3.0 call_data_dissector@Base 2.1.0 diff --git a/debian/libwsutil0.symbols b/debian/libwsutil0.symbols index 8b1a4898bc..175e7b7bed 100644 --- a/debian/libwsutil0.symbols +++ b/debian/libwsutil0.symbols @@ -8,6 +8,10 @@ libwsutil.so.0 libwsutil0 #MINVER# ascii_strdown_inplace@Base 1.10.0 ascii_strup_inplace@Base 1.10.0 bitswap_buf_inplace@Base 1.12.0~rc1 + bytes_to_hexstr@Base 3.5.0 + bytes_to_hexstr_punct@Base 3.5.0 + bytes_to_str@Base 3.5.0 + bytestring_to_str@Base 3.5.0 codec_decode@Base 3.1.0 codec_get_channels@Base 3.1.0 codec_get_frequency@Base 3.1.0 diff --git a/epan/ftypes/ftype-protocol.c b/epan/ftypes/ftype-protocol.c index 61936ef48e..760ef39977 100644 --- a/epan/ftypes/ftype-protocol.c +++ b/epan/ftypes/ftype-protocol.c @@ -10,7 +10,7 @@ #include #include -#include +#include #include #include diff --git a/epan/to_str-int.h b/epan/to_str-int.h index d42d941ca7..2e145c5f8c 100644 --- a/epan/to_str-int.h +++ b/epan/to_str-int.h @@ -71,18 +71,6 @@ char *qword_to_hex(char *out, guint64 qword); */ char *qword_to_hex_punct(char *out, guint64 qword, char punct); -/** - * bytes_to_hexstr_punct() - * - * Output hex represetation of guint8 ad array, and return pointer after last character. - * Each byte will be separated with punct character (cannot be NUL). - * It always output full representation (padded with 0). - * - * String is not NUL terminated by this routine. - * There needs to be at least len * 3 - 1 bytes in the buffer. - */ -char *bytes_to_hexstr_punct(char *out, const guint8 *ad, size_t len, char punct); - /** * oct_to_str_back() * diff --git a/epan/to_str.c b/epan/to_str.c index f79d0bb522..4a8fc1c03d 100644 --- a/epan/to_str.c +++ b/epan/to_str.c @@ -125,122 +125,6 @@ qword_to_hex_punct(char *out, guint64 qword, char punct) return out; } -/* - * This does *not* null-terminate the string. It returns a pointer - * to the position in the string following the last character it - * puts there, so that the caller can either put the null terminator - * in or can append more stuff to the buffer. - * - * There needs to be at least len * 2 bytes left in the buffer. - */ -char * -bytes_to_hexstr(char *out, const guint8 *ad, size_t len) -{ - size_t i; - - if (!ad) - REPORT_DISSECTOR_BUG("Null pointer passed to bytes_to_hexstr()"); - - for (i = 0; i < len; i++) - out = byte_to_hex(out, ad[i]); - return out; -} - -/* - * This does *not* null-terminate the string. It returns a pointer - * to the position in the string following the last character it - * puts there, so that the caller can either put the null terminator - * in or can append more stuff to the buffer. - * - * There needs to be at least len * 3 - 1 bytes left in the buffer. - */ -char * -bytes_to_hexstr_punct(char *out, const guint8 *ad, size_t len, char punct) -{ - size_t i; - - if (!ad) - REPORT_DISSECTOR_BUG("Null pointer passed to bytes_to_hexstr_punct()"); - - out = byte_to_hex(out, ad[0]); - for (i = 1; i < len; i++) { - *out++ = punct; - out = byte_to_hex(out, ad[i]); - } - return out; -} - -/* Max string length for displaying byte string. */ -#define MAX_BYTE_STR_LEN 72 - -/* Routine to convert a sequence of bytes to a hex string, one byte/two hex - * digits at at a time, with a specified punctuation character between - * the bytes. - * - * If punct is '\0', no punctuation is applied (and thus - * the resulting string is (len-1) bytes shorter) - */ -gchar * -bytestring_to_str(wmem_allocator_t *scope, const guint8 *ad, size_t len, const char punct) -{ - gchar *buf; - size_t buflen = len; - gchar *buf_ptr; - int truncated = 0; - - if (len == 0) - return wmem_strdup(scope, ""); - - if (!ad) - REPORT_DISSECTOR_BUG("Null pointer passed to bytestring_to_str()"); - - if (!punct) - return bytes_to_str(scope, ad, len); - - buf=(gchar *)wmem_alloc(scope, MAX_BYTE_STR_LEN+3+1); - if (buflen > MAX_BYTE_STR_LEN/3) { /* bd_len > 16 */ - truncated = 1; - buflen = MAX_BYTE_STR_LEN/3; - } - - buf_ptr = bytes_to_hexstr_punct(buf, ad, buflen, punct); /* max MAX_BYTE_STR_LEN-1 bytes */ - - if (truncated) { - *buf_ptr++ = punct; /* 1 byte */ - buf_ptr = g_stpcpy(buf_ptr, UTF8_HORIZONTAL_ELLIPSIS); /* 3 bytes */ - } - - *buf_ptr = '\0'; - return buf; -} - -char * -bytes_to_str(wmem_allocator_t *scope, const guint8 *bd, size_t bd_len) -{ - gchar *cur; - gchar *cur_ptr; - int truncated = 0; - - if (!bd) - REPORT_DISSECTOR_BUG("Null pointer passed to bytes_to_str()"); - - cur=(gchar *)wmem_alloc(scope, MAX_BYTE_STR_LEN+3+1); - if (bd_len == 0) { cur[0] = '\0'; return cur; } - - if (bd_len > MAX_BYTE_STR_LEN/2) { /* bd_len > 24 */ - truncated = 1; - bd_len = MAX_BYTE_STR_LEN/2; - } - - cur_ptr = bytes_to_hexstr(cur, bd, bd_len); /* max MAX_BYTE_STR_LEN bytes */ - - if (truncated) - cur_ptr = g_stpcpy(cur_ptr, UTF8_HORIZONTAL_ELLIPSIS); /* 3 bytes */ - - *cur_ptr = '\0'; /* 1 byte */ - return cur; -} - static int guint32_to_str_buf_len(const guint32 u) { diff --git a/epan/to_str.h b/epan/to_str.h index 1e20e007c0..eebb0e7ad4 100644 --- a/epan/to_str.h +++ b/epan/to_str.h @@ -20,6 +20,7 @@ #include #include "ws_symbol_export.h" #include +#include #define GUID_STR_LEN 37 #define MAX_ADDR_STR_LEN 256 @@ -168,39 +169,6 @@ WS_DLL_PUBLIC char *word_to_hex(char *out, guint16 word); */ WS_DLL_PUBLIC char *dword_to_hex(char *out, guint32 dword); -/** Turn an array of bytes into a string showing the bytes in hex. - * - * @param scope memory allocation scheme used - * @param bd A pointer to the byte array - * @param bd_len The length of the byte array - * @return A pointer to the formatted string - */ -WS_DLL_PUBLIC char *bytes_to_str(wmem_allocator_t *scope, const guint8 *bd, size_t bd_len); - -/** Turn an array of bytes into a string showing the bytes in hex, - * separated by a punctuation character. - * - * @param scope memory allocation scheme used - * @param ad A pointer to the byte array - * @param len The length of the byte array - * @param punct The punctuation character - * @return A pointer to the formatted string - * - * @see bytes_to_str() - */ -WS_DLL_PUBLIC gchar *bytestring_to_str(wmem_allocator_t *scope, const guint8 *ad, size_t len, const char punct); - -/** - * bytes_to_hexstr() - * - * Output hex represetation of guint8 ad array, and return pointer after last character. - * It always output full representation (padded with 0). - * - * String is not NUL terminated by this routine. - * There needs to be at least len * 2 bytes in the buffer. - */ -WS_DLL_PUBLIC char *bytes_to_hexstr(char *out, const guint8 *ad, size_t len); - /** * uint_to_str_back() * diff --git a/wsutil/CMakeLists.txt b/wsutil/CMakeLists.txt index e636bb3196..67be67c403 100644 --- a/wsutil/CMakeLists.txt +++ b/wsutil/CMakeLists.txt @@ -64,6 +64,7 @@ set(WSUTIL_PUBLIC_HEADERS strtoi.h tempfile.h time_util.h + to_str.h type_util.h unicode-utils.h utf8_entities.h @@ -121,6 +122,7 @@ set(WSUTIL_COMMON_FILES report_message.c tempfile.c time_util.c + to_str.c type_util.c unicode-utils.c glib-compat.c diff --git a/wsutil/to_str.c b/wsutil/to_str.c new file mode 100644 index 0000000000..eebe2c116d --- /dev/null +++ b/wsutil/to_str.c @@ -0,0 +1,188 @@ +/* wsutil/to_str.c + * Routines for utilities to convert various other types to strings. + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "to_str.h" + +#include +#include + + +static inline char +low_nibble_of_octet_to_hex(guint8 oct) +{ + /* At least one version of Apple's C compiler/linker is buggy, causing + a complaint from the linker about the "literal C string section" + not ending with '\0' if we initialize a 16-element "char" array with + a 16-character string, the fact that initializing such an array with + such a string is perfectly legitimate ANSI C nonwithstanding, the 17th + '\0' byte in the string nonwithstanding. */ + static const gchar hex_digits[16] = + { '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + + return hex_digits[oct & 0xF]; +} + +static inline char * +byte_to_hex(char *out, guint32 dword) +{ + *out++ = low_nibble_of_octet_to_hex(dword >> 4); + *out++ = low_nibble_of_octet_to_hex(dword); + return out; +} + +/* + * This does *not* null-terminate the string. It returns a pointer + * to the position in the string following the last character it + * puts there, so that the caller can either put the null terminator + * in or can append more stuff to the buffer. + * + * There needs to be at least len * 2 bytes left in the buffer. + */ +char * +bytes_to_hexstr(char *out, const guint8 *ad, size_t len) +{ + size_t i; + + if (!ad) { + ws_warning("Null pointer passed to bytes_to_hexstr()"); + return NULL; + } + + for (i = 0; i < len; i++) + out = byte_to_hex(out, ad[i]); + return out; +} + +/* + * This does *not* null-terminate the string. It returns a pointer + * to the position in the string following the last character it + * puts there, so that the caller can either put the null terminator + * in or can append more stuff to the buffer. + * + * There needs to be at least len * 3 - 1 bytes left in the buffer. + */ +char * +bytes_to_hexstr_punct(char *out, const guint8 *ad, size_t len, char punct) +{ + size_t i; + + if (!ad) { + ws_warning("Null pointer passed to bytes_to_hexstr_punct()"); + return NULL; + } + + out = byte_to_hex(out, ad[0]); + for (i = 1; i < len; i++) { + *out++ = punct; + out = byte_to_hex(out, ad[i]); + } + return out; +} + +/* Max string length for displaying byte string. */ +#define MAX_BYTE_STR_LEN 72 + +/* Routine to convert a sequence of bytes to a hex string, one byte/two hex + * digits at at a time, with a specified punctuation character between + * the bytes. + * + * If punct is '\0', no punctuation is applied (and thus + * the resulting string is (len-1) bytes shorter) + */ +gchar * +bytestring_to_str(wmem_allocator_t *scope, const guint8 *ad, size_t len, const char punct) +{ + gchar *buf; + size_t buflen = len; + gchar *buf_ptr; + int truncated = 0; + + if (len == 0) { + ws_warning("Zero length passed to bytestring_to_str()"); + return wmem_strdup(scope, "(zero length)"); + } + + if (!ad) { + ws_warning("Null pointer passed to bytestring_to_str()"); + return wmem_strdup(scope, "(null pointer)"); + } + + if (!punct) + return bytes_to_str(scope, ad, len); + + buf=(gchar *)wmem_alloc(scope, MAX_BYTE_STR_LEN+3+1); + if (buflen > MAX_BYTE_STR_LEN/3) { /* bd_len > 16 */ + truncated = 1; + buflen = MAX_BYTE_STR_LEN/3; + } + + buf_ptr = bytes_to_hexstr_punct(buf, ad, buflen, punct); /* max MAX_BYTE_STR_LEN-1 bytes */ + + if (truncated) { + *buf_ptr++ = punct; /* 1 byte */ + buf_ptr = g_stpcpy(buf_ptr, UTF8_HORIZONTAL_ELLIPSIS); /* 3 bytes */ + } + + *buf_ptr = '\0'; + return buf; +} + +char * +bytes_to_str(wmem_allocator_t *scope, const guint8 *bd, size_t bd_len) +{ + gchar *cur; + gchar *cur_ptr; + int truncated = 0; + + if (bd_len == 0) { + ws_warning("Zero length passed to bytes_to_str()"); + return wmem_strdup(scope, "(zero length)"); + } + + if (!bd) { + ws_warning("Null pointer passed to bytes_to_str()"); + return wmem_strdup(scope, "(null pointer)"); + } + + cur=(gchar *)wmem_alloc(scope, MAX_BYTE_STR_LEN+3+1); + if (bd_len > MAX_BYTE_STR_LEN/2) { /* bd_len > 24 */ + truncated = 1; + bd_len = MAX_BYTE_STR_LEN/2; + } + + cur_ptr = bytes_to_hexstr(cur, bd, bd_len); /* max MAX_BYTE_STR_LEN bytes */ + + if (truncated) + cur_ptr = g_stpcpy(cur_ptr, UTF8_HORIZONTAL_ELLIPSIS); /* 3 bytes */ + + *cur_ptr = '\0'; /* 1 byte */ + return cur; +} + +/* + * Editor modelines - https://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 8 + * tab-width: 8 + * indent-tabs-mode: t + * End: + * + * vi: set shiftwidth=8 tabstop=8 noexpandtab: + * :indentSize=8:tabSize=8:noTabs=false: + */ diff --git a/wsutil/to_str.h b/wsutil/to_str.h new file mode 100644 index 0000000000..6ed4d69334 --- /dev/null +++ b/wsutil/to_str.h @@ -0,0 +1,72 @@ +/* wsutil/to_str.h + * Definitions for utilities to convert various other types to strings. + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef __WSUTIL_TO_STR_H__ +#define __WSUTIL_TO_STR_H__ + +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * bytes_to_hexstr() + * + * Output hex represetation of guint8 ad array, and return pointer after last character. + * It always output full representation (padded with 0). + * + * String is not NUL terminated by this routine. + * There needs to be at least len * 2 bytes in the buffer. + */ +WS_DLL_PUBLIC char *bytes_to_hexstr(char *out, const guint8 *ad, size_t len); + +/** + * bytes_to_hexstr_punct() + * + * Output hex represetation of guint8 ad array, and return pointer after last character. + * Each byte will be separated with punct character (cannot be NUL). + * It always output full representation (padded with 0). + * + * String is not NUL terminated by this routine. + * There needs to be at least len * 3 - 1 bytes in the buffer. + */ +WS_DLL_PUBLIC char *bytes_to_hexstr_punct(char *out, const guint8 *ad, size_t len, char punct); + +/** Turn an array of bytes into a string showing the bytes in hex, + * separated by a punctuation character. + * + * @param scope memory allocation scheme used + * @param ad A pointer to the byte array + * @param len The length of the byte array + * @param punct The punctuation character + * @return A pointer to the formatted string + * + * @see bytes_to_str() + */ +WS_DLL_PUBLIC gchar *bytestring_to_str(wmem_allocator_t *scope, const guint8 *ad, size_t len, const char punct); + +/** Turn an array of bytes into a string showing the bytes in hex. + * + * @param scope memory allocation scheme used + * @param bd A pointer to the byte array + * @param bd_len The length of the byte array + * @return A pointer to the formatted string + */ +WS_DLL_PUBLIC char *bytes_to_str(wmem_allocator_t *scope, const guint8 *bd, size_t bd_len); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __TO_STR_H__ */