advapi32: Fix RegEnumValueW when enumerating long values.

Bernhard Übelacker bernhardu at vr-web.de
Sun Jun 21 11:25:48 CDT 2015


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




More information about the wine-patches mailing list