Module: wine
Branch: master
Commit: 95f2cc0f15b1dde0318e75e2a7f21957fa76af55
URL: https://gitlab.winehq.org/wine/wine/-/commit/95f2cc0f15b1dde0318e75e2a7f219…
Author: Francois Gouget <fgouget(a)codeweavers.com>
Date: Fri Mar 3 16:23:07 2023 +0100
advapi32/tests: Fix the RegEnumValueA() tests in UTF-8 locales.
On Windows RegEnumValueA() is buggy such that when the value name
buffer is too small, it may way overestimate the required data buffer
size, sometimes returning more than the sufficiently large buffer it was
provided, in which case that buffer is untouched and thus not
NUL-terminated.
So modify the tests to accept this broken result and avoid checking
out-of-bounds data.
Wine-Bug: https://bugs.winehq.org//show_bug.cgi?id=53172
---
dlls/advapi32/tests/registry.c | 29 ++++++++++++++++++++---------
1 file changed, 20 insertions(+), 9 deletions(-)
diff --git a/dlls/advapi32/tests/registry.c b/dlls/advapi32/tests/registry.c
index 480e96ef6ee..524c3e0ef76 100644
--- a/dlls/advapi32/tests/registry.c
+++ b/dlls/advapi32/tests/registry.c
@@ -476,7 +476,7 @@ static void test_enum_value(void)
{
DWORD res;
HKEY test_key;
- char value[20], data[20];
+ char value[20], data[30];
WCHAR valueW[20], dataW[20];
DWORD val_count, data_count, type;
@@ -542,39 +542,50 @@ static void test_enum_value(void)
/* overflow name */
val_count = 3;
- data_count = 20;
+ data_count = 16;
type = 1234;
strcpy( value, "xxxxxxxxxx" );
memset( data, 'x', sizeof(data) );
+ data[sizeof(data)-1] = '\0';
res = RegEnumValueA( test_key, 0, value, &val_count, NULL, &type, (LPBYTE)data, &data_count );
ok( res == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %ld\n", res );
ok( val_count == 3, "val_count set to %ld\n", val_count );
- /* Chinese, Japanese, and Korean editions of Windows 10 sometimes set data_count to a higher value */
+ /* In double-byte and UTF-8 locales Windows 10 may set data_count > 7,
+ * potentially even more than the declared buffer size, in which case the
+ * buffer is not NUL-terminated.
+ */
ok( data_count == 7 || broken( data_count > 7 ), "data_count set to %ld instead of 7\n", data_count );
ok( type == REG_SZ, "type %ld is not REG_SZ\n", type );
- /* v5.1.2600.0 (XP Home and Professional) does not touch value or data in this case */
+ /* v5.1.2600.0 (XP Home and Professional) does not touch value or data in
+ * this case. Neither does Windows 10 21H1 in UTF-8 locales.
+ */
ok( !strcmp( value, "Te" ) || !strcmp( value, "xxxxxxxxxx" ),
"value set to '%s' instead of 'Te' or 'xxxxxxxxxx'\n", value );
ok( !strcmp( data, "foobar" ) || !strcmp( data, "xxxxxxx" ) ||
- broken( data_count > 7 && strspn( data, "x" ) == data_count && data[data_count] == 0 ),
+ broken( data_count > 7 && data_count < 16 &&
+ strspn( data, "x" ) == data_count && data[data_count] == 0 ) ||
+ broken( data_count >= 16 && strspn( data, "x" ) == sizeof(data) - 1 ),
"data set to '%s' instead of 'foobar' or x's, data_count=%lu\n", data, data_count );
/* overflow empty name */
val_count = 0;
- data_count = 20;
+ data_count = 16;
type = 1234;
strcpy( value, "xxxxxxxxxx" );
memset( data, 'x', sizeof(data) );
+ data[sizeof(data)-1] = '\0';
res = RegEnumValueA( test_key, 0, value, &val_count, NULL, &type, (LPBYTE)data, &data_count );
ok( res == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %ld\n", res );
ok( val_count == 0, "val_count set to %ld\n", val_count );
- /* Chinese, Japanese, and Korean editions of Windows 10 sometimes set data_count to a higher value */
+ /* See comment in 'overflow name' section */
ok( data_count == 7 || broken( data_count > 7 ), "data_count set to %ld instead of 7\n", data_count );
ok( type == REG_SZ, "type %ld is not REG_SZ\n", type );
ok( !strcmp( value, "xxxxxxxxxx" ), "value set to '%s'\n", value );
- /* v5.1.2600.0 (XP Home and Professional) does not touch data in this case */
+ /* See comment in 'overflow name' section */
ok( !strcmp( data, "foobar" ) || !strcmp( data, "xxxxxxx" ) ||
- broken( data_count > 7 && strspn( data, "x" ) == data_count && data[data_count] == 0 ),
+ broken( data_count > 7 && data_count < 16 &&
+ strspn( data, "x" ) == data_count && data[data_count] == 0 ) ||
+ broken( data_count >= 16 && strspn( data, "x" ) == sizeof(data) - 1 ),
"data set to '%s' instead of 'foobar' or x's, data_count=%lu\n", data, data_count );
/* overflow data */
Module: wine
Branch: master
Commit: 9c22a5ea63c6be01e257f05bbed23e03d5a7f407
URL: https://gitlab.winehq.org/wine/wine/-/commit/9c22a5ea63c6be01e257f05bbed23e…
Author: Rémi Bernon <rbernon(a)codeweavers.com>
Date: Fri Mar 3 09:30:37 2023 +0100
win32u: Check GUID_NULL display device if desktop atom is missing.
When using nulldrv, there's no module to call __wine_set_user_driver and
the user driver is still lazy_load_driver when get_display_driver gets
called during desktop windows creation.
Then, load_desktop_driver fails as it cannot find the not-yet-created
desktop window atom, and fails later explorer.exe window creations such
as the systray window.
Other processes don't suffer from this as they wait for the desktop
window to be fully created, and its atom will be eventually set.
This change makes sure that we succeed in the case nulldrv was selected
by explorer.exe, while still failing in case of error with another user
driver as it would fail to open the right display device GUID.
---
dlls/win32u/driver.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c
index 3f676dc5796..eb736de272d 100644
--- a/dlls/win32u/driver.c
+++ b/dlls/win32u/driver.c
@@ -923,6 +923,8 @@ static const WCHAR guid_key_suffixW[] = {'}','\\','0','0','0','0'};
static BOOL load_desktop_driver( HWND hwnd )
{
+ static const WCHAR guid_nullW[] = {'0','0','0','0','0','0','0','0','-','0','0','0','0','-','0','0','0','0','-',
+ '0','0','0','0','-','0','0','0','0','0','0','0','0','0','0','0','0',0};
WCHAR key[ARRAYSIZE(guid_key_prefixW) + 40 + ARRAYSIZE(guid_key_suffixW)], *ptr;
char buf[4096];
KEY_VALUE_PARTIAL_INFORMATION *info = (void *)buf;
@@ -946,9 +948,15 @@ static BOOL load_desktop_driver( HWND hwnd )
memcpy( key, guid_key_prefixW, sizeof(guid_key_prefixW) );
ptr = key + ARRAYSIZE(guid_key_prefixW);
if (NtQueryInformationAtom( guid_atom, AtomBasicInformation, buf, sizeof(buf), NULL ))
- return FALSE;
- memcpy( ptr, abi->Name, abi->NameLength );
- ptr += abi->NameLength / sizeof(WCHAR);
+ {
+ wcscpy( ptr, guid_nullW );
+ ptr += ARRAY_SIZE(guid_nullW) - 1;
+ }
+ else
+ {
+ memcpy( ptr, abi->Name, abi->NameLength );
+ ptr += abi->NameLength / sizeof(WCHAR);
+ }
memcpy( ptr, guid_key_suffixW, sizeof(guid_key_suffixW) );
ptr += ARRAY_SIZE(guid_key_suffixW);