Sam Dennis : advapi32: Fix undocumented behaviour in ReqQueryValueEx when ' count' and 'type' point to the same address.

Alexandre Julliard julliard at winehq.org
Fri Dec 14 07:39:52 CST 2007


Module: wine
Branch: master
Commit: 1590b1f73198f34a5f49a177e66c315aa0aa00a5
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=1590b1f73198f34a5f49a177e66c315aa0aa00a5

Author: Sam Dennis <samuel.howard.dennis at gmail.com>
Date:   Fri Dec 14 05:48:28 2007 +0000

advapi32: Fix undocumented behaviour in ReqQueryValueEx when 'count' and 'type' point to the same address.

---

 dlls/advapi32/registry.c       |    9 +++++----
 dlls/advapi32/tests/registry.c |    4 ++++
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/dlls/advapi32/registry.c b/dlls/advapi32/registry.c
index 4b9f29d..d7f6dc4 100644
--- a/dlls/advapi32/registry.c
+++ b/dlls/advapi32/registry.c
@@ -1217,7 +1217,7 @@ LSTATUS WINAPI RegQueryValueExA( HKEY hkey, LPCSTR name, LPDWORD reserved, LPDWO
 {
     NTSTATUS status;
     ANSI_STRING nameA;
-    DWORD total_size;
+    DWORD total_size, datalen = 0;
     char buffer[256], *buf_ptr = buffer;
     KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)buffer;
     static const int info_size = offsetof( KEY_VALUE_PARTIAL_INFORMATION, Data );
@@ -1228,6 +1228,7 @@ LSTATUS WINAPI RegQueryValueExA( HKEY hkey, LPCSTR name, LPDWORD reserved, LPDWO
     if ((data && !count) || reserved) return ERROR_INVALID_PARAMETER;
     if (!(hkey = get_special_root_hkey( hkey ))) return ERROR_INVALID_HANDLE;
 
+    if (count) datalen = *count;
     if (!data && count) *count = 0;
 
     /* this matches Win9x behaviour - NT sets *type to a random value */
@@ -1270,21 +1271,21 @@ LSTATUS WINAPI RegQueryValueExA( HKEY hkey, LPCSTR name, LPDWORD reserved, LPDWO
                                        total_size - info_size );
             if (data && len)
             {
-                if (len > *count) status = STATUS_BUFFER_OVERFLOW;
+                if (len > datalen) status = STATUS_BUFFER_OVERFLOW;
                 else
                 {
                     RtlUnicodeToMultiByteN( (char*)data, len, NULL, (WCHAR *)(buf_ptr + info_size),
                                             total_size - info_size );
                     /* if the type is REG_SZ and data is not 0-terminated
                      * and there is enough space in the buffer NT appends a \0 */
-                    if (len < *count && data[len-1]) data[len] = 0;
+                    if (len < datalen && data[len-1]) data[len] = 0;
                 }
             }
             total_size = len + info_size;
         }
         else if (data)
         {
-            if (total_size - info_size > *count) status = STATUS_BUFFER_OVERFLOW;
+            if (total_size - info_size > datalen) status = STATUS_BUFFER_OVERFLOW;
             else memcpy( data, buf_ptr + info_size, total_size - info_size );
         }
     }
diff --git a/dlls/advapi32/tests/registry.c b/dlls/advapi32/tests/registry.c
index 1c50d2a..23af17c 100644
--- a/dlls/advapi32/tests/registry.c
+++ b/dlls/advapi32/tests/registry.c
@@ -580,6 +580,10 @@ static void test_query_value_ex(void)
     ret = RegQueryValueExA(HKEY_CLASSES_ROOT, "Nonexistent Value", NULL, &type, buffer, &size);
     ok(ret == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %d\n", ret);
     ok(size == sizeof(buffer), "size shouldn't have been changed to %d\n", size);
+
+    size = 4;
+    ret = RegQueryValueExA(hkey_main, "BIN32", NULL, &size, buffer, &size);
+    ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret);
 }
 
 static void test_get_value(void)




More information about the wine-cvs mailing list