From e7acb9f6968d48217a4210dd91b742e82f80bc72 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Mon, 13 Jan 2025 20:43:22 +0000 Subject: [PATCH] GetDlgItemTextW_alloc: use the right memchr. When retrieving Unicode text from an edit box in the GUI configurer, we were using plain memchr() to look for a terminating NUL. But of course you have to use wmemchr() to look for a UTF-16 NUL, or else memchr() will generate a false positive on the UTF-16 version of (at least) any ASCII character! (I also have to provide a fallback implementation of wmemchr for the w32old builds, which don't have it in the libc they build against. It's as simple as possible, and we use the libc version where possible.) --- cmake/cmake.h.in | 1 + cmake/platforms/windows.cmake | 1 + defs.h | 5 +++++ windows/CMakeLists.txt | 3 +++ windows/utils/getdlgitemtext_alloc.c | 4 +++- windows/utils/wmemchr.c | 15 +++++++++++++++ 6 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 windows/utils/wmemchr.c diff --git a/cmake/cmake.h.in b/cmake/cmake.h.in index 3d36b3d0..cb389cb6 100644 --- a/cmake/cmake.h.in +++ b/cmake/cmake.h.in @@ -15,6 +15,7 @@ #cmakedefine01 HAVE_GETNAMEDPIPECLIENTPROCESSID #cmakedefine01 HAVE_SETDEFAULTDLLDIRECTORIES #cmakedefine01 HAVE_STRTOUMAX +#cmakedefine01 HAVE_WMEMCHR #cmakedefine01 HAVE_DWMAPI_H #cmakedefine NOT_X_WINDOWS diff --git a/cmake/platforms/windows.cmake b/cmake/platforms/windows.cmake index 481809ec..e87f3380 100644 --- a/cmake/platforms/windows.cmake +++ b/cmake/platforms/windows.cmake @@ -53,6 +53,7 @@ define_negation(NO_HTMLHELP HAVE_HTMLHELP_H) check_include_files("winsock2.h;afunix.h" HAVE_AFUNIX_H) check_symbol_exists(strtoumax "inttypes.h" HAVE_STRTOUMAX) +check_symbol_exists(wmemchr "wchar.h" HAVE_WMEMCHR) check_symbol_exists(AddDllDirectory "windows.h" HAVE_ADDDLLDIRECTORY) check_symbol_exists(SetDefaultDllDirectories "windows.h" HAVE_SETDEFAULTDLLDIRECTORIES) diff --git a/defs.h b/defs.h index 0ac23ee2..0e56eb78 100644 --- a/defs.h +++ b/defs.h @@ -53,6 +53,11 @@ uintmax_t strtoumax(const char *nptr, char **endptr, int base); #define SIZEu "zu" #endif +#if !HAVE_WMEMCHR +/* Work around lack of wmemchr in older MSVC */ +wchar_t *wmemchr(const wchar_t *s, wchar_t c, size_t n); +#endif + #if defined __GNUC__ || defined __clang__ /* * On MinGW, the correct compiler format checking for vsnprintf() etc diff --git a/windows/CMakeLists.txt b/windows/CMakeLists.txt index 960a440d..7d4fcadb 100644 --- a/windows/CMakeLists.txt +++ b/windows/CMakeLists.txt @@ -42,6 +42,9 @@ add_sources_from_current_dir(utils if(NOT HAVE_STRTOUMAX) add_sources_from_current_dir(utils utils/strtoumax.c) endif() +if(NOT HAVE_WMEMCHR) + add_sources_from_current_dir(utils utils/wmemchr.c) +endif() add_sources_from_current_dir(eventloop cliloop.c handle-wait.c) add_sources_from_current_dir(console diff --git a/windows/utils/getdlgitemtext_alloc.c b/windows/utils/getdlgitemtext_alloc.c index 8db32901..8de62a3b 100644 --- a/windows/utils/getdlgitemtext_alloc.c +++ b/windows/utils/getdlgitemtext_alloc.c @@ -4,6 +4,8 @@ * string is dynamically allocated; caller must free. */ +#include + #include "putty.h" char *GetDlgItemText_alloc(HWND hwnd, int id) @@ -27,7 +29,7 @@ wchar_t *GetDlgItemTextW_alloc(HWND hwnd, int id) do { sgrowarray_nm(ret, size, size); GetDlgItemTextW(hwnd, id, ret, size); - } while (!memchr(ret, '\0', size-1)); + } while (!wmemchr(ret, L'\0', size-1)); return ret; } diff --git a/windows/utils/wmemchr.c b/windows/utils/wmemchr.c new file mode 100644 index 00000000..7ccdfe3c --- /dev/null +++ b/windows/utils/wmemchr.c @@ -0,0 +1,15 @@ +/* + * Work around lack of wmemchr in older MSVC libraries. + */ + +#include + +#include "defs.h" + +wchar_t *wmemchr(const wchar_t *s, wchar_t c, size_t n) +{ + for (; n != 0; s++, n--) + if (*s == c) + return (wchar_t *)s; + return NULL; +}