RegEnumValue[AW] need to update the data size on buffer overflow
(spotted by Massimo <max@veneto.com>).
diff --git a/dlls/advapi32/registry.c b/dlls/advapi32/registry.c
index a9cddb8..61858af 100644
--- a/dlls/advapi32/registry.c
+++ b/dlls/advapi32/registry.c
@@ -1076,7 +1076,7 @@
if (info->NameLength/sizeof(WCHAR) >= *val_count)
{
status = STATUS_BUFFER_OVERFLOW;
- goto done;
+ goto overflow;
}
memcpy( value, info->Name, info->NameLength );
*val_count = info->NameLength / sizeof(WCHAR);
@@ -1088,7 +1088,7 @@
if (total_size - info->DataOffset > *count)
{
status = STATUS_BUFFER_OVERFLOW;
- goto done;
+ goto overflow;
}
memcpy( data, buf_ptr + info->DataOffset, total_size - info->DataOffset );
if (total_size - info->DataOffset <= *count-sizeof(WCHAR) && is_string(info->Type))
@@ -1102,6 +1102,7 @@
}
else status = STATUS_SUCCESS;
+ overflow:
if (type) *type = info->Type;
if (count) *count = info->DataLength;
@@ -1154,21 +1155,6 @@
if (status) goto done;
- if (value)
- {
- DWORD len;
-
- RtlUnicodeToMultiByteSize( &len, info->Name, info->NameLength );
- if (len >= *val_count)
- {
- status = STATUS_BUFFER_OVERFLOW;
- goto done;
- }
- RtlUnicodeToMultiByteN( value, len, NULL, info->Name, info->NameLength );
- value[len] = 0;
- *val_count = len;
- }
-
if (is_string(info->Type))
{
DWORD len;
@@ -1176,16 +1162,15 @@
total_size - info->DataOffset );
if (data && len)
{
- if (len > *count)
+ if (len > *count) status = STATUS_BUFFER_OVERFLOW;
+ else
{
- status = STATUS_BUFFER_OVERFLOW;
- goto done;
+ RtlUnicodeToMultiByteN( data, len, NULL, (WCHAR *)(buf_ptr + info->DataOffset),
+ total_size - info->DataOffset );
+ /* 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;
}
- RtlUnicodeToMultiByteN( data, len, NULL, (WCHAR *)(buf_ptr + info->DataOffset),
- total_size - info->DataOffset );
- /* 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;
}
info->DataLength = len;
}
@@ -1194,6 +1179,29 @@
if (total_size - info->DataOffset > *count) status = STATUS_BUFFER_OVERFLOW;
else memcpy( data, buf_ptr + info->DataOffset, total_size - info->DataOffset );
}
+
+ if (value && !status)
+ {
+ DWORD len;
+
+ RtlUnicodeToMultiByteSize( &len, info->Name, info->NameLength );
+ if (len >= *val_count)
+ {
+ status = STATUS_BUFFER_OVERFLOW;
+ if (*val_count)
+ {
+ len = *val_count - 1;
+ RtlUnicodeToMultiByteN( value, len, NULL, info->Name, info->NameLength );
+ value[len] = 0;
+ }
+ }
+ else
+ {
+ RtlUnicodeToMultiByteN( value, len, NULL, info->Name, info->NameLength );
+ value[len] = 0;
+ *val_count = len;
+ }
+ }
}
else status = STATUS_SUCCESS;
diff --git a/memory/registry.c b/memory/registry.c
index c6bd0a2..e3c57d0 100644
--- a/memory/registry.c
+++ b/memory/registry.c
@@ -533,21 +533,6 @@
if (status) goto done;
- if (value)
- {
- DWORD len;
-
- RtlUnicodeToMultiByteSize( &len, info->Name, info->NameLength );
- if (len >= *val_count)
- {
- status = STATUS_BUFFER_OVERFLOW;
- goto done;
- }
- RtlUnicodeToMultiByteN( value, len, NULL, info->Name, info->NameLength );
- value[len] = 0;
- *val_count = len;
- }
-
if (is_string(info->Type))
{
DWORD len;
@@ -555,16 +540,15 @@
total_size - info->DataOffset );
if (data && len)
{
- if (len > *count)
+ if (len > *count) status = STATUS_BUFFER_OVERFLOW;
+ else
{
- status = STATUS_BUFFER_OVERFLOW;
- goto done;
+ RtlUnicodeToMultiByteN( data, len, NULL, (WCHAR *)(buf_ptr + info->DataOffset),
+ total_size - info->DataOffset );
+ /* 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;
}
- RtlUnicodeToMultiByteN( data, len, NULL, (WCHAR *)(buf_ptr + info->DataOffset),
- total_size - info->DataOffset );
- /* 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;
}
info->DataLength = len;
}
@@ -573,6 +557,29 @@
if (total_size - info->DataOffset > *count) status = STATUS_BUFFER_OVERFLOW;
else memcpy( data, buf_ptr + info->DataOffset, total_size - info->DataOffset );
}
+
+ if (value && !status)
+ {
+ DWORD len;
+
+ RtlUnicodeToMultiByteSize( &len, info->Name, info->NameLength );
+ if (len >= *val_count)
+ {
+ status = STATUS_BUFFER_OVERFLOW;
+ if (*val_count)
+ {
+ len = *val_count - 1;
+ RtlUnicodeToMultiByteN( value, len, NULL, info->Name, info->NameLength );
+ value[len] = 0;
+ }
+ }
+ else
+ {
+ RtlUnicodeToMultiByteN( value, len, NULL, info->Name, info->NameLength );
+ value[len] = 0;
+ *val_count = len;
+ }
+ }
}
else status = STATUS_SUCCESS;