=?UTF-8?Q?Bernhard=20=C3=9Cbelacker=20?=: advapi32: Fix RegEnumValueW when enumerating long values.
Alexandre Julliard
julliard at wine.codeweavers.com
Mon Jun 22 07:44:59 CDT 2015
Module: wine
Branch: master
Commit: 443ef6e7a6026f6aaa5ffcfcbc33d582da780ac5
URL: http://source.winehq.org/git/wine.git/?a=commit;h=443ef6e7a6026f6aaa5ffcfcbc33d582da780ac5
Author: Bernhard Übelacker <bernhardu at vr-web.de>
Date: Sun Jun 21 18:25:48 2015 +0200
advapi32: Fix RegEnumValueW when enumerating long values.
---
dlls/advapi32/registry.c | 68 +++++++++++++++++++-----------------------
dlls/advapi32/tests/registry.c | 13 ++++++++
2 files changed, 44 insertions(+), 37 deletions(-)
diff --git a/dlls/advapi32/registry.c b/dlls/advapi32/registry.c
index 30130b1..f8bf21a 100644
--- a/dlls/advapi32/registry.c
+++ b/dlls/advapi32/registry.c
@@ -1922,53 +1922,47 @@ LSTATUS WINAPI RegEnumValueW( HKEY hkey, DWORD index, LPWSTR value, LPDWORD val_
status = NtEnumerateValueKey( hkey, index, KeyValueFullInformation,
buffer, total_size, &total_size );
- if (status && status != STATUS_BUFFER_OVERFLOW) goto done;
- if (value || data)
+ /* retry with a dynamically allocated buffer */
+ while (status == STATUS_BUFFER_OVERFLOW)
{
- /* retry with a dynamically allocated buffer */
- while (status == STATUS_BUFFER_OVERFLOW)
- {
- if (buf_ptr != buffer) heap_free( buf_ptr );
- if (!(buf_ptr = heap_alloc( total_size )))
- return ERROR_NOT_ENOUGH_MEMORY;
- info = (KEY_VALUE_FULL_INFORMATION *)buf_ptr;
- status = NtEnumerateValueKey( hkey, index, KeyValueFullInformation,
- buf_ptr, total_size, &total_size );
- }
+ if (buf_ptr != buffer) heap_free( buf_ptr );
+ if (!(buf_ptr = heap_alloc( total_size ))) return ERROR_NOT_ENOUGH_MEMORY;
+ info = (KEY_VALUE_FULL_INFORMATION *)buf_ptr;
+ status = NtEnumerateValueKey( hkey, index, KeyValueFullInformation,
+ buf_ptr, total_size, &total_size );
+ }
- if (status) goto done;
+ if (status) goto done;
- if (value)
+ if (value)
+ {
+ if (info->NameLength/sizeof(WCHAR) >= *val_count)
{
- if (info->NameLength/sizeof(WCHAR) >= *val_count)
- {
- status = STATUS_BUFFER_OVERFLOW;
- goto overflow;
- }
- memcpy( value, info->Name, info->NameLength );
- *val_count = info->NameLength / sizeof(WCHAR);
- value[*val_count] = 0;
+ status = STATUS_BUFFER_OVERFLOW;
+ goto overflow;
}
+ memcpy( value, info->Name, info->NameLength );
+ *val_count = info->NameLength / sizeof(WCHAR);
+ value[*val_count] = 0;
+ }
- if (data)
+ if (data)
+ {
+ if (total_size - info->DataOffset > *count)
{
- if (total_size - info->DataOffset > *count)
- {
- status = STATUS_BUFFER_OVERFLOW;
- goto overflow;
- }
- memcpy( data, buf_ptr + info->DataOffset, total_size - info->DataOffset );
- if (total_size - info->DataOffset <= *count-sizeof(WCHAR) && is_string(info->Type))
- {
- /* if the type is REG_SZ and data is not 0-terminated
- * and there is enough space in the buffer NT appends a \0 */
- WCHAR *ptr = (WCHAR *)(data + total_size - info->DataOffset);
- if (ptr > (WCHAR *)data && ptr[-1]) *ptr = 0;
- }
+ status = STATUS_BUFFER_OVERFLOW;
+ goto overflow;
+ }
+ memcpy( data, buf_ptr + info->DataOffset, total_size - info->DataOffset );
+ if (total_size - info->DataOffset <= *count-sizeof(WCHAR) && is_string(info->Type))
+ {
+ /* if the type is REG_SZ and data is not 0-terminated
+ * and there is enough space in the buffer NT appends a \0 */
+ WCHAR *ptr = (WCHAR *)(data + total_size - info->DataOffset);
+ if (ptr > (WCHAR *)data && ptr[-1]) *ptr = 0;
}
}
- else status = STATUS_SUCCESS;
overflow:
if (type) *type = info->Type;
diff --git a/dlls/advapi32/tests/registry.c b/dlls/advapi32/tests/registry.c
index c801384..561101b 100644
--- a/dlls/advapi32/tests/registry.c
+++ b/dlls/advapi32/tests/registry.c
@@ -522,6 +522,8 @@ 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];
+ int i;
/* create the working key for new 'Test' value */
res = RegCreateKeyA( hkey_main, "TestKey", &test_key );
@@ -710,6 +712,17 @@ 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 */
+ for (i = 0; i < sizeof(longW)/sizeof(WCHAR); i++) longW[i] = 'x';
+ longW[i - 1] = 0;
+ 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\n", data_count );
+
cleanup:
RegDeleteKeyA(test_key, "");
RegCloseKey(test_key);
More information about the wine-cvs
mailing list