diff options
author | João Valverde <j@v6e.pt> | 2022-12-06 19:27:24 +0000 |
---|---|---|
committer | João Valverde <j@v6e.pt> | 2022-12-09 19:17:05 +0000 |
commit | a74027ad00c24e3ae2d7855af9195fe2609c1a93 (patch) | |
tree | 38034f7290b3a631a2d161d59f2400bb65892f0c /wiretap | |
parent | c64eaf87afa65b01fe73a8befdc5716aee34e876 (diff) |
wiretap: Validate UTF-8 encoding for pcapng
Validate UTF-8 encoding for pcapng string options. To
avoid two unnecessary memory allocations for invalid strings and
make the code cleaner a new wtap_block_add_string_option_owned()
function is used.
Add UTF-8 debug check for wiretap API.
Fixes #18703.
Diffstat (limited to 'wiretap')
-rw-r--r-- | wiretap/pcapng.c | 12 | ||||
-rw-r--r-- | wiretap/wtap_opttypes.c | 17 | ||||
-rw-r--r-- | wiretap/wtap_opttypes.h | 11 |
3 files changed, 39 insertions, 1 deletions
diff --git a/wiretap/pcapng.c b/wiretap/pcapng.c index 6f6b977e99..4a51d4a499 100644 --- a/wiretap/pcapng.c +++ b/wiretap/pcapng.c @@ -700,7 +700,17 @@ void pcapng_process_string_option(wtapng_block_t *wblock, guint16 option_code, guint16 option_length, const guint8 *option_content) { - wtap_block_add_string_option(wblock->block, option_code, (const char *)option_content, option_length); + const char *opt = (const char *)option_content; + size_t optlen = option_length; + char *str; + + /* Validate UTF-8 encoding. */ + if (g_utf8_validate(opt, optlen, NULL)) + str = g_strndup(opt, optlen); + else + str = g_utf8_make_valid(opt, optlen); + + wtap_block_add_string_option_owned(wblock->block, option_code, str); } void diff --git a/wiretap/wtap_opttypes.c b/wiretap/wtap_opttypes.c index 268d31a1d2..753e72f63b 100644 --- a/wiretap/wtap_opttypes.c +++ b/wiretap/wtap_opttypes.c @@ -19,6 +19,7 @@ #include <wsutil/glib-compat.h> #include <wsutil/inet_ipv6.h> +#include <wsutil/unicode-utils.h> #if 0 #define wtap_debug(...) ws_warning(__VA_ARGS__) @@ -942,6 +943,21 @@ wtap_block_add_string_option(wtap_block_t block, guint option_id, const char *va if (ret != WTAP_OPTTYPE_SUCCESS) return ret; opt->value.stringval = g_strndup(value, value_length); + WS_UTF_8_CHECK(opt->value.stringval, -1); + return WTAP_OPTTYPE_SUCCESS; +} + +wtap_opttype_return_val +wtap_block_add_string_option_owned(wtap_block_t block, guint option_id, char *value) +{ + wtap_opttype_return_val ret; + wtap_option_t *opt; + + ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_STRING, &opt); + if (ret != WTAP_OPTTYPE_SUCCESS) + return ret; + opt->value.stringval = value; + WS_UTF_8_CHECK(opt->value.stringval, -1); return WTAP_OPTTYPE_SUCCESS; } @@ -955,6 +971,7 @@ wtap_block_add_string_option_vformat(wtap_block_t block, guint option_id, const if (ret != WTAP_OPTTYPE_SUCCESS) return ret; opt->value.stringval = ws_strdup_vprintf(format, va); + WS_UTF_8_CHECK(opt->value.stringval, -1); return WTAP_OPTTYPE_SUCCESS; } diff --git a/wiretap/wtap_opttypes.h b/wiretap/wtap_opttypes.h index 93300161b6..b21c2e1efa 100644 --- a/wiretap/wtap_opttypes.h +++ b/wiretap/wtap_opttypes.h @@ -782,6 +782,17 @@ wtap_block_get_ipv6_option_value(wtap_block_t block, guint option_id, ws_in6_add WS_DLL_PUBLIC wtap_opttype_return_val wtap_block_add_string_option(wtap_block_t block, guint option_id, const char *value, gsize value_length); +/** Add a string option to a block taking ownership of the null-terminated string. + * + * @param[in] block Block to which to add the option + * @param[in] option_id Identifier value for option + * @param[in] value Value of option + * @return wtap_opttype_return_val - WTAP_OPTTYPE_SUCCESS if successful, + * error code otherwise + */ +WS_DLL_PUBLIC wtap_opttype_return_val +wtap_block_add_string_option_owned(wtap_block_t block, guint option_id, char *value); + /** Add a string option to a block with a printf-formatted string as its value * * @param[in] block Block to which to add the option |