From: Bernhard Übelacker Subject: advapi32: Fix RegEnumValueW when enumerating long values. Message-Id: <1434903948-31560-1-git-send-email-bernhardu@vr-web.de> Date: Sun, 21 Jun 2015 18:25:48 +0200 Bug #38796 When RegEnumValueW is used to retrieve the needed buffer size, NtEnumerateValueKey is just called with the fixed buffer. If this is not sufficient long a wrong value of the needed space is put into the count variable, and the caller of RegEnumValueW is again calling with an insufficient buffer size. --- dlls/advapi32/registry.c | 2 +- dlls/advapi32/tests/registry.c | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/dlls/advapi32/registry.c b/dlls/advapi32/registry.c index 30130b1..e68d089 100644 --- a/dlls/advapi32/registry.c +++ b/dlls/advapi32/registry.c @@ -1924,7 +1924,7 @@ LSTATUS WINAPI RegEnumValueW( HKEY hkey, DWORD index, LPWSTR value, LPDWORD val_ buffer, total_size, &total_size ); if (status && status != STATUS_BUFFER_OVERFLOW) goto done; - if (value || data) + if (value || data || status == STATUS_BUFFER_OVERFLOW) { /* retry with a dynamically allocated buffer */ while (status == STATUS_BUFFER_OVERFLOW) diff --git a/dlls/advapi32/tests/registry.c b/dlls/advapi32/tests/registry.c index c801384..e80a9e4 100644 --- a/dlls/advapi32/tests/registry.c +++ b/dlls/advapi32/tests/registry.c @@ -522,6 +522,11 @@ static void test_enum_value(void) static const WCHAR foobarW[] = {'f','o','o','b','a','r',0}; static const WCHAR testW[] = {'T','e','s','t',0}; static const WCHAR xxxW[] = {'x','x','x','x','x','x','x','x',0}; + WCHAR longW[128]; /* tests the overflow case for the fixed "char buffer[]" in RegEnumValueW */ + int i; + for (i = 0; i < sizeof(longW)/sizeof(WCHAR); i++) + longW[i] = 'x'; + longW[sizeof(longW)-1] = 0; /* create the working key for new 'Test' value */ res = RegCreateKeyA( hkey_main, "TestKey", &test_key ); @@ -710,6 +715,15 @@ static void test_enum_value(void) ok( !memcmp( valueW, testW, sizeof(testW) ), "value is not 'Test'\n" ); ok( !memcmp( dataW, foobarW, sizeof(foobarW) ), "data is not 'foobar'\n" ); + /* tests the overflow case for the fixed "char buffer[]" in RegEnumValueW */ + res = RegSetValueExW( test_key, testW, 0, REG_SZ, (const BYTE *)longW, sizeof(longW) ); + ok( res == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", res ); + data_count = 20; + type = 1234; + res = RegEnumValueW( test_key, 0, NULL, NULL, NULL, &type, NULL, &data_count); + ok( res == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", res ); + ok( data_count == sizeof(longW), "data_count set to %d instead of %d\n", data_count, sizeof(longW) ); + cleanup: RegDeleteKeyA(test_key, ""); RegCloseKey(test_key); -- 2.1.4