forked from osmocom/wireshark
Move two functions from epan to wsutil/str_util
Move epan_memmem() and epan_strcasestr() to wsutil/str_util. Rename to ws_memmem() and ws_strcasestr(). Add compile time check for a system implementation and use that if available. We invoke those functions using a wrapper to avoid exposing _GNU_SOURCE outside of the implementation.pespin/osmux-wip
parent
ede0bc5d61
commit
ef8125e3ae
|
@ -92,6 +92,13 @@ if (APPLE)
|
|||
check_function_exists("CFPropertyListCreateWithStream" HAVE_CFPROPERTYLISTCREATEWITHSTREAM)
|
||||
cmake_pop_check_state()
|
||||
endif()
|
||||
if(UNIX)
|
||||
cmake_push_check_state()
|
||||
list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
|
||||
check_function_exists("memmem" HAVE_MEMMEM)
|
||||
check_function_exists("strcasestr" HAVE_STRCASESTR)
|
||||
cmake_pop_check_state()
|
||||
endif()
|
||||
|
||||
#Struct members
|
||||
include(CheckStructHasMember)
|
||||
|
|
|
@ -250,6 +250,12 @@
|
|||
/* Define if you have the 'strptime' function. */
|
||||
#cmakedefine HAVE_STRPTIME 1
|
||||
|
||||
/* Define if you have the 'memmem' function. */
|
||||
#cmakedefine HAVE_MEMMEM 1
|
||||
|
||||
/* Define if you have the 'strcasestr' function. */
|
||||
#cmakedefine HAVE_STRCASESTR 1
|
||||
|
||||
/* Define to 1 if `st_birthtime' is a member of `struct stat'. */
|
||||
#cmakedefine HAVE_STRUCT_STAT_ST_BIRTHTIME 1
|
||||
|
||||
|
|
|
@ -590,12 +590,10 @@ libwireshark.so.0 libwireshark0 #MINVER#
|
|||
epan_inspect_enums_bsearch@Base 3.7.0
|
||||
epan_inspect_enums_count@Base 3.7.0
|
||||
epan_load_settings@Base 2.3.0
|
||||
epan_memmem@Base 1.9.1
|
||||
epan_new@Base 1.12.0~rc1
|
||||
epan_plugins_supported@Base 3.5.0
|
||||
epan_register_plugin@Base 2.5.0
|
||||
epan_set_always_visible@Base 3.5.1
|
||||
epan_strcasestr@Base 1.9.1
|
||||
escape_string@Base 1.9.1
|
||||
escape_string_len@Base 1.9.1
|
||||
esp_sa_record_add_from_dissector@Base 1.12.0~rc1
|
||||
|
|
|
@ -399,6 +399,7 @@ libwsutil.so.0 libwsutil0 #MINVER#
|
|||
ws_log_write_always_full@Base 3.5.0
|
||||
ws_logv@Base 3.5.0
|
||||
ws_logv_full@Base 3.5.0
|
||||
ws_memmem@Base 3.7.0
|
||||
ws_mempbrk_compile@Base 1.99.4
|
||||
ws_mempbrk_exec@Base 1.99.4
|
||||
ws_optarg@Base 3.5.1
|
||||
|
@ -418,6 +419,7 @@ libwsutil.so.0 libwsutil0 #MINVER#
|
|||
ws_regex_matches@Base 3.7.0
|
||||
ws_regex_pattern@Base 3.7.0
|
||||
ws_socket_ptoa@Base 3.1.1
|
||||
ws_strcasestr@Base 3.7.0
|
||||
ws_strtoi16@Base 2.3.0
|
||||
ws_strtoi32@Base 2.3.0
|
||||
ws_strtoi64@Base 2.3.0
|
||||
|
|
|
@ -230,8 +230,8 @@ dissect_k12(tvbuff_t* tvb,packet_info* pinfo,proto_tree* tree, void* data _U_)
|
|||
|
||||
if (! handles ) {
|
||||
for (i=0 ; i < nk12_handles; i++) {
|
||||
if ( epan_strcasestr(pinfo->pseudo_header->k12.stack_file, k12_handles[i].match)
|
||||
|| epan_strcasestr(pinfo->pseudo_header->k12.input_name, k12_handles[i].match) ) {
|
||||
if ( ws_strcasestr(pinfo->pseudo_header->k12.stack_file, k12_handles[i].match)
|
||||
|| ws_strcasestr(pinfo->pseudo_header->k12.input_name, k12_handles[i].match) ) {
|
||||
handles = k12_handles[i].handles;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -284,7 +284,7 @@ xmpp_unknown_attrs(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, xmpp
|
|||
proto_tree_add_string(tree, hf_xmpp_xmlns, tvb, attr->offset, attr->length, attr->value);
|
||||
else {
|
||||
/*xmlns may looks like xmlns:abbrev="sth"*/
|
||||
const gchar *xmlns_needle = epan_strcasestr((const char *)keys->data, "xmlns:");
|
||||
const gchar *xmlns_needle = ws_strcasestr((const char *)keys->data, "xmlns:");
|
||||
if (xmlns_needle && xmlns_needle == keys->data) {
|
||||
proto_tree_add_string_format(tree, hf_xmpp_xmlns, tvb, attr->offset, attr->length, attr->value,"%s: %s", (gchar*)keys->data, attr->value);
|
||||
} else {
|
||||
|
@ -581,7 +581,7 @@ xmpp_xml_frame_to_element_t(wmem_allocator_t *pool, xml_frame_t *xml_frame, xmpp
|
|||
g_hash_table_insert(node->attrs,(gpointer)attr->name,(gpointer)attr);
|
||||
|
||||
/*checking that attr->name looks like xmlns:ns*/
|
||||
xmlns_needle = epan_strcasestr(attr->name, "xmlns");
|
||||
xmlns_needle = ws_strcasestr(attr->name, "xmlns");
|
||||
|
||||
if(xmlns_needle == attr->name)
|
||||
{
|
||||
|
@ -654,7 +654,7 @@ attr_find_pred(gpointer key, gpointer value _U_, gpointer user_data)
|
|||
|
||||
if( strcmp(attr_name, "xmlns") == 0 )
|
||||
{
|
||||
const gchar *first_occur = epan_strcasestr((const char *)key, "xmlns:");
|
||||
const gchar *first_occur = ws_strcasestr((const char *)key, "xmlns:");
|
||||
if(first_occur && first_occur == key)
|
||||
return TRUE;
|
||||
else
|
||||
|
|
|
@ -545,7 +545,7 @@ cmp_contains(const fvalue_t *fv_a, const fvalue_t *fv_b)
|
|||
GByteArray *a = fv_a->value.bytes;
|
||||
GByteArray *b = fv_b->value.bytes;
|
||||
|
||||
if (epan_memmem(a->data, a->len, b->data, b->len)) {
|
||||
if (ws_memmem(a->data, a->len, b->data, b->len)) {
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -1357,37 +1357,6 @@ xml_escape(const gchar *unescaped)
|
|||
return g_string_free(buffer, FALSE);
|
||||
}
|
||||
|
||||
|
||||
/* Return the first occurrence of needle in haystack.
|
||||
* If not found, return NULL.
|
||||
* If either haystack or needle has 0 length, return NULL.
|
||||
* Algorithm copied from GNU's glibc 2.3.2 memmem() under LGPL 2.1+ */
|
||||
const guint8 *
|
||||
epan_memmem(const guint8 *haystack, guint haystack_len,
|
||||
const guint8 *needle, guint needle_len)
|
||||
{
|
||||
const guint8 *begin;
|
||||
const guint8 *const last_possible = haystack + haystack_len - needle_len;
|
||||
|
||||
if (needle_len == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (needle_len > haystack_len) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (begin = haystack ; begin <= last_possible; ++begin) {
|
||||
if (begin[0] == needle[0] &&
|
||||
!memcmp(&begin[1], needle + 1,
|
||||
needle_len - 1)) {
|
||||
return begin;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan the search string to make sure it's valid hex. Return the
|
||||
* number of bytes in nbytes.
|
||||
|
@ -1479,20 +1448,6 @@ convert_string_case(const char *string, gboolean case_insensitive)
|
|||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
epan_strcasestr(const char *haystack, const char *needle)
|
||||
{
|
||||
gsize hlen = strlen(haystack);
|
||||
gsize nlen = strlen(needle);
|
||||
|
||||
while (hlen-- >= nlen) {
|
||||
if (!g_ascii_strncasecmp(haystack, needle, nlen))
|
||||
return haystack;
|
||||
haystack++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *
|
||||
string_or_null(const char *string)
|
||||
{
|
||||
|
|
|
@ -261,22 +261,6 @@ gboolean byte_array_equal(GByteArray *ba1, GByteArray *ba2);
|
|||
WS_DLL_PUBLIC
|
||||
gchar* xml_escape(const gchar *unescaped);
|
||||
|
||||
/**
|
||||
* Return the first occurrence of needle in haystack.
|
||||
* Algorithm copied from GNU's glibc 2.3.2 memcmp()
|
||||
*
|
||||
* @param haystack The data to search
|
||||
* @param haystack_len The length of the search data
|
||||
* @param needle The string to look for
|
||||
* @param needle_len The length of the search string
|
||||
* @return A pointer to the first occurrence of "needle" in
|
||||
* "haystack". If "needle" isn't found or is NULL, or if
|
||||
* "needle_len" is 0, NULL is returned.
|
||||
*/
|
||||
WS_DLL_PUBLIC
|
||||
const guint8 * epan_memmem(const guint8 *haystack, guint haystack_len,
|
||||
const guint8 *needle, guint needle_len);
|
||||
|
||||
/** Scan a string to make sure it's valid hex.
|
||||
*
|
||||
* @param string The string to validate
|
||||
|
@ -298,17 +282,6 @@ guint8 * convert_string_to_hex(const char *string, size_t *nbytes);
|
|||
WS_DLL_PUBLIC
|
||||
char * convert_string_case(const char *string, gboolean case_insensitive);
|
||||
|
||||
/** Finds the first occurrence of string 'needle' in string 'haystack'.
|
||||
* The matching is done in a case insensitive manner.
|
||||
*
|
||||
* @param haystack The string possibly containing the substring
|
||||
* @param needle The substring to be searched
|
||||
* @return A pointer into 'haystack' where 'needle' is first found.
|
||||
* Otherwise it returns NULL.
|
||||
*/
|
||||
WS_DLL_PUBLIC
|
||||
const char * epan_strcasestr(const char *haystack, const char *needle);
|
||||
|
||||
/** Guarantee a non-null string.
|
||||
*
|
||||
* @param string The string to check
|
||||
|
@ -319,6 +292,7 @@ const char * string_or_null(const char *string);
|
|||
|
||||
WS_DLL_PUBLIC
|
||||
int escape_string_len(const char *string);
|
||||
|
||||
WS_DLL_PUBLIC
|
||||
char * escape_string(char *dst, const char *string);
|
||||
|
||||
|
|
|
@ -4448,7 +4448,7 @@ tvb_find_tvb(tvbuff_t *haystack_tvb, tvbuff_t *needle_tvb, const gint haystack_o
|
|||
check_offset_length(haystack_tvb, haystack_offset, -1,
|
||||
&haystack_abs_offset, &haystack_abs_length);
|
||||
|
||||
location = epan_memmem(haystack_data + haystack_abs_offset, haystack_abs_length,
|
||||
location = ws_memmem(haystack_data + haystack_abs_offset, haystack_abs_length,
|
||||
needle_data, needle_len);
|
||||
|
||||
if (location) {
|
||||
|
|
|
@ -8,9 +8,12 @@
|
|||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include "config.h"
|
||||
#include "str_util.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
int
|
||||
ws_xton(char ch)
|
||||
{
|
||||
|
@ -116,6 +119,60 @@ isdigit_string(const guchar *str)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/* Return the first occurrence of needle in haystack.
|
||||
* If not found, return NULL.
|
||||
* If either haystack or needle has 0 length, return NULL.*/
|
||||
const guint8 *
|
||||
ws_memmem(const void *_haystack, size_t haystack_len,
|
||||
const void *_needle, size_t needle_len)
|
||||
{
|
||||
#ifdef HAVE_MEMMEM
|
||||
return memmem(_haystack, haystack_len, _needle, needle_len);
|
||||
#else
|
||||
/* Algorithm copied from GNU's glibc 2.3.2 memmem() under LGPL 2.1+ */
|
||||
const guint8 *haystack = _haystack;
|
||||
const guint8 *needle = _needle;
|
||||
const guint8 *begin;
|
||||
const guint8 *const last_possible = haystack + haystack_len - needle_len;
|
||||
|
||||
if (needle_len == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (needle_len > haystack_len) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (begin = haystack ; begin <= last_possible; ++begin) {
|
||||
if (begin[0] == needle[0] &&
|
||||
!memcmp(&begin[1], needle + 1,
|
||||
needle_len - 1)) {
|
||||
return begin;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
#endif /* HAVE_MEMMEM */
|
||||
}
|
||||
|
||||
const char *
|
||||
ws_strcasestr(const char *haystack, const char *needle)
|
||||
{
|
||||
#ifdef HAVE_STRCASESTR
|
||||
return strcasestr(haystack, needle);
|
||||
#else
|
||||
gsize hlen = strlen(haystack);
|
||||
gsize nlen = strlen(needle);
|
||||
|
||||
while (hlen-- >= nlen) {
|
||||
if (!g_ascii_strncasecmp(haystack, needle, nlen))
|
||||
return haystack;
|
||||
haystack++;
|
||||
}
|
||||
return NULL;
|
||||
#endif /* HAVE_STRCASESTR */
|
||||
}
|
||||
|
||||
#define FORMAT_SIZE_UNIT_MASK 0x00ff
|
||||
#define FORMAT_SIZE_PFX_MASK 0xff00
|
||||
|
||||
|
|
|
@ -79,6 +79,32 @@ gboolean isprint_utf8_string(const gchar *str, guint length);
|
|||
WS_DLL_PUBLIC
|
||||
gboolean isdigit_string(const guchar *str);
|
||||
|
||||
/**
|
||||
* Return the first occurrence of needle in haystack.
|
||||
*
|
||||
* @param haystack The data to search
|
||||
* @param haystack_len The length of the search data
|
||||
* @param needle The string to look for
|
||||
* @param needle_len The length of the search string
|
||||
* @return A pointer to the first occurrence of "needle" in
|
||||
* "haystack". If "needle" isn't found or is NULL, or if
|
||||
* "needle_len" is 0, NULL is returned.
|
||||
*/
|
||||
WS_DLL_PUBLIC
|
||||
const guint8 *ws_memmem(const void *haystack, size_t haystack_len,
|
||||
const void *needle, size_t needle_len);
|
||||
|
||||
/** Finds the first occurrence of string 'needle' in string 'haystack'.
|
||||
* The matching is done in a case insensitive manner.
|
||||
*
|
||||
* @param haystack The string possibly containing the substring
|
||||
* @param needle The substring to be searched
|
||||
* @return A pointer into 'haystack' where 'needle' is first found.
|
||||
* Otherwise it returns NULL.
|
||||
*/
|
||||
WS_DLL_PUBLIC
|
||||
const char *ws_strcasestr(const char *haystack, const char *needle);
|
||||
|
||||
WS_DLL_PUBLIC
|
||||
int ws_xton(char ch);
|
||||
|
||||
|
|
Loading…
Reference in New Issue