From b894199f723a169dc25854be1a407969bb901c47 Mon Sep 17 00:00:00 2001 From: akallabeth Date: Mon, 12 Feb 2024 10:39:37 +0100 Subject: [PATCH] [winpr,collections] add generic string clone functions The ArrayList, HashTable, ... New functions require void* (*fkt)(const void* ptr) type functions. Provide a generic wrapper for CHAR and WCHAR strdup to eliminate warnings. Also export a corresponding free function to avoid issues with runtime differences. --- channels/drdynvc/client/drdynvc_main.c | 4 +- client/X11/xf_event.c | 4 +- client/X11/xf_keyboard.c | 4 +- libfreerdp/common/assistance.c | 2 +- libfreerdp/core/gateway/http.c | 16 ++----- libfreerdp/emu/scard/smartcard_emulate.c | 20 ++------- winpr/include/winpr/collections.h | 5 +++ .../file/test/TestFileFindFirstFile.c | 10 +---- winpr/libwinpr/utils/CMakeLists.txt | 1 + winpr/libwinpr/utils/collections/HashTable.c | 4 +- winpr/libwinpr/utils/collections/Object.c | 42 +++++++++++++++++++ 11 files changed, 67 insertions(+), 45 deletions(-) create mode 100644 winpr/libwinpr/utils/collections/Object.c diff --git a/channels/drdynvc/client/drdynvc_main.c b/channels/drdynvc/client/drdynvc_main.c index e117a57fd..61b2b4197 100644 --- a/channels/drdynvc/client/drdynvc_main.c +++ b/channels/drdynvc/client/drdynvc_main.c @@ -331,8 +331,8 @@ static IWTSVirtualChannelManager* dvcman_new(drdynvcPlugin* plugin) if (!dvcman->plugin_names) goto fail; obj = ArrayList_Object(dvcman->plugin_names); - obj->fnObjectNew = _strdup; - obj->fnObjectFree = free; + obj->fnObjectNew = winpr_ObjectStringClone; + obj->fnObjectFree = winpr_ObjectStringFree; dvcman->plugins = ArrayList_New(TRUE); if (!dvcman->plugins) diff --git a/client/X11/xf_event.c b/client/X11/xf_event.c index 6fb32be97..fbb93a302 100644 --- a/client/X11/xf_event.c +++ b/client/X11/xf_event.c @@ -187,8 +187,8 @@ BOOL xf_event_action_script_init(xfContext* xfc) obj = ArrayList_Object(xfc->xevents); WINPR_ASSERT(obj); - obj->fnObjectNew = _strdup; - obj->fnObjectFree = free; + obj->fnObjectNew = winpr_ObjectStringClone; + obj->fnObjectFree = winpr_ObjectStringFree; ActionScript = freerdp_settings_get_string(settings, FreeRDP_ActionScript); sprintf_s(command, sizeof(command), "%s xevent", ActionScript); actionScript = popen(command, "r"); diff --git a/client/X11/xf_keyboard.c b/client/X11/xf_keyboard.c index 022ca123e..9b575c2eb 100644 --- a/client/X11/xf_keyboard.c +++ b/client/X11/xf_keyboard.c @@ -104,8 +104,8 @@ static BOOL xf_keyboard_action_script_init(xfContext* xfc) obj = ArrayList_Object(xfc->keyCombinations); WINPR_ASSERT(obj); - obj->fnObjectNew = _strdup; - obj->fnObjectFree = free; + obj->fnObjectNew = winpr_ObjectStringClone; + obj->fnObjectFree = winpr_ObjectStringFree; sprintf_s(command, sizeof(command), "%s key", ActionScript); keyScript = popen(command, "r"); diff --git a/libfreerdp/common/assistance.c b/libfreerdp/common/assistance.c index fb0cd007e..dc76d6ab5 100644 --- a/libfreerdp/common/assistance.c +++ b/libfreerdp/common/assistance.c @@ -1373,7 +1373,7 @@ static BOOL setup_string(wArrayList* list) if (!obj) return FALSE; obj->fnObjectFree = free; - // obj->fnObjectNew = _strdup; + // obj->fnObjectNew = wwinpr_ObjectStringClone; return TRUE; } diff --git a/libfreerdp/core/gateway/http.c b/libfreerdp/core/gateway/http.c index ed856fcf9..8d3094550 100644 --- a/libfreerdp/core/gateway/http.c +++ b/libfreerdp/core/gateway/http.c @@ -134,14 +134,6 @@ static BOOL strings_equals_nocase(const void* obj1, const void* obj2) return _stricmp(obj1, obj2) == 0; } -static void* copy_string(const void* ptr) -{ - const char* str = ptr; - if (!str) - return NULL; - return _strdup(ptr); -} - HttpContext* http_context_new(void) { HttpContext* context = (HttpContext*)calloc(1, sizeof(HttpContext)); @@ -157,10 +149,10 @@ HttpContext* http_context_new(void) if (!key || !value) goto fail; - key->fnObjectFree = free; - key->fnObjectNew = copy_string; - value->fnObjectFree = free; - value->fnObjectNew = copy_string; + key->fnObjectFree = winpr_ObjectStringFree; + key->fnObjectNew = winpr_ObjectStringClone; + value->fnObjectFree = winpr_ObjectStringFree; + value->fnObjectNew = winpr_ObjectStringClone; return context; diff --git a/libfreerdp/emu/scard/smartcard_emulate.c b/libfreerdp/emu/scard/smartcard_emulate.c index ad13b6264..9824399d6 100644 --- a/libfreerdp/emu/scard/smartcard_emulate.c +++ b/libfreerdp/emu/scard/smartcard_emulate.c @@ -200,18 +200,6 @@ static BOOL wchar_compare(const void* a, const void* b) return _wcscmp(wa, wb) == 0; } -static void* str_copy(const void* ptr) -{ - const char* src = ptr; - return _strdup(src); -} - -static void* wstr_copy(const void* ptr) -{ - const WCHAR* src = ptr; - return _wcsdup(src); -} - static SCardContext* scard_context_new(void) { SCardContext* ctx = calloc(1, sizeof(SCardContext)); @@ -239,8 +227,8 @@ static SCardContext* scard_context_new(void) WINPR_ASSERT(val); key->fnObjectEquals = char_compare; - key->fnObjectNew = str_copy; - key->fnObjectFree = free; + key->fnObjectNew = winpr_ObjectStringClone; + key->fnObjectFree = winpr_ObjectStringFree; val->fnObjectFree = free; } @@ -256,8 +244,8 @@ static SCardContext* scard_context_new(void) WINPR_ASSERT(val); key->fnObjectEquals = wchar_compare; - key->fnObjectNew = wstr_copy; - key->fnObjectFree = free; + key->fnObjectNew = winpr_ObjectWStringClone; + key->fnObjectFree = winpr_ObjectStringFree; val->fnObjectFree = free; } diff --git a/winpr/include/winpr/collections.h b/winpr/include/winpr/collections.h index 921176013..ec3de729c 100644 --- a/winpr/include/winpr/collections.h +++ b/winpr/include/winpr/collections.h @@ -62,6 +62,11 @@ extern "C" OBJECT_EQUALS_FN fnObjectEquals; } wObject; + /* utility function with compatible arguments for string data */ + WINPR_API void* winpr_ObjectStringClone(const void* pvstr); + WINPR_API void* winpr_ObjectWStringClone(const void* pvstr); + WINPR_API void winpr_ObjectStringFree(void* pvstr); + /* System.Collections.Queue */ typedef struct s_wQueue wQueue; diff --git a/winpr/libwinpr/file/test/TestFileFindFirstFile.c b/winpr/libwinpr/file/test/TestFileFindFirstFile.c index 3cca72baa..04829a3cb 100644 --- a/winpr/libwinpr/file/test/TestFileFindFirstFile.c +++ b/winpr/libwinpr/file/test/TestFileFindFirstFile.c @@ -189,12 +189,6 @@ static BOOL find_first_file_fail(const char* FilePath) return FALSE; } -static void* string_dup(const void* val) -{ - const char* str = (const char*)val; - return _strdup(str); -} - static int TestFileFindFirstFileA(const char* str) { int rc = -1; @@ -216,8 +210,8 @@ static int TestFileFindFirstFileA(const char* str) if (!files) return -3; wObject* obj = ArrayList_Object(files); - obj->fnObjectFree = free; - obj->fnObjectNew = string_dup; + obj->fnObjectFree = winpr_ObjectStringFree; + obj->fnObjectNew = winpr_ObjectStringClone; if (!create_layout(BasePath, files)) return -1; diff --git a/winpr/libwinpr/utils/CMakeLists.txt b/winpr/libwinpr/utils/CMakeLists.txt index e57f49bf5..91c7353e8 100644 --- a/winpr/libwinpr/utils/CMakeLists.txt +++ b/winpr/libwinpr/utils/CMakeLists.txt @@ -59,6 +59,7 @@ endif() set(COLLECTIONS_SRCS + collections/Object.c collections/Queue.c collections/Stack.c collections/PubSub.c diff --git a/winpr/libwinpr/utils/collections/HashTable.c b/winpr/libwinpr/utils/collections/HashTable.c index ddb45f7f1..ee3ff9927 100644 --- a/winpr/libwinpr/utils/collections/HashTable.c +++ b/winpr/libwinpr/utils/collections/HashTable.c @@ -96,12 +96,12 @@ UINT32 HashTable_StringHash(const void* key) void* HashTable_StringClone(const void* str) { - return _strdup((const char*)str); + return winpr_ObjectStringClone(str); } void HashTable_StringFree(void* str) { - free(str); + winpr_ObjectStringFree(str); } static INLINE BOOL HashTable_IsProbablePrime(size_t oddNumber) diff --git a/winpr/libwinpr/utils/collections/Object.c b/winpr/libwinpr/utils/collections/Object.c new file mode 100644 index 000000000..8bee86c04 --- /dev/null +++ b/winpr/libwinpr/utils/collections/Object.c @@ -0,0 +1,42 @@ +/** + * WinPR: Windows Portable Runtime + * Collections + * + * Copyright 2024 Armin Novak + * Copyright 2024 Thincast Technologies GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include + +void* winpr_ObjectStringClone(const void* pvstr) +{ + const char* str = pvstr; + if (!str) + return NULL; + return _strdup(str); +} + +void* winpr_ObjectWStringClone(const void* pvstr) +{ + const WCHAR* str = pvstr; + if (!str) + return NULL; + return _wcsdup(str); +} + +void winpr_ObjectStringFree(void* pvstr) +{ + free(pvstr); +}