Module: wine Branch: master Commit: 94d2b4742c358e15d336d4a48e2c1354efa5de5c URL: https://source.winehq.org/git/wine.git/?a=commit;h=94d2b4742c358e15d336d4a48...
Author: Alexandre Julliard julliard@winehq.org Date: Tue Dec 3 08:30:36 2019 +0100
kernelbase: Fix assumptions about 0-size output buffer in ntdll Unicode conversion functions.
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/kernelbase/file.c | 21 ++++++++++++++++++--- dlls/kernelbase/registry.c | 16 +++++++++------- dlls/kernelbase/string.c | 3 +-- 3 files changed, 28 insertions(+), 12 deletions(-)
diff --git a/dlls/kernelbase/file.c b/dlls/kernelbase/file.c index 77a7398580..23ca5629a3 100644 --- a/dlls/kernelbase/file.c +++ b/dlls/kernelbase/file.c @@ -292,10 +292,25 @@ DWORD file_name_WtoA( LPCWSTR src, INT srclen, LPSTR dest, INT destlen ) DWORD ret;
if (srclen < 0) srclen = lstrlenW( src ) + 1; - if (oem_file_apis) - RtlUnicodeToOemN( dest, destlen, &ret, src, srclen * sizeof(WCHAR) ); + if (!destlen) + { + if (oem_file_apis) + { + UNICODE_STRING strW; + strW.Buffer = (WCHAR *)src; + strW.Length = srclen * sizeof(WCHAR); + ret = RtlUnicodeStringToOemSize( &strW ) - 1; + } + else + RtlUnicodeToMultiByteSize( &ret, src, srclen * sizeof(WCHAR) ); + } else - RtlUnicodeToMultiByteN( dest, destlen, &ret, src, srclen * sizeof(WCHAR) ); + { + if (oem_file_apis) + RtlUnicodeToOemN( dest, destlen, &ret, src, srclen * sizeof(WCHAR) ); + else + RtlUnicodeToMultiByteN( dest, destlen, &ret, src, srclen * sizeof(WCHAR) ); + } return ret; }
diff --git a/dlls/kernelbase/registry.c b/dlls/kernelbase/registry.c index d3364dbcee..1fee41ec5e 100644 --- a/dlls/kernelbase/registry.c +++ b/dlls/kernelbase/registry.c @@ -915,7 +915,7 @@ LSTATUS WINAPI RegQueryInfoKeyA( HKEY hkey, LPSTR class, LPDWORD class_len, LPDW NTSTATUS status; char buffer[256], *buf_ptr = buffer; KEY_FULL_INFORMATION *info = (KEY_FULL_INFORMATION *)buffer; - DWORD total_size, len; + DWORD total_size;
TRACE( "(%p,%p,%d,%p,%p,%p,%p,%p,%p,%p,%p)\n", hkey, class, class_len ? *class_len : 0, reserved, subkeys, max_subkey, values, max_value, max_data, security, modif ); @@ -940,19 +940,21 @@ LSTATUS WINAPI RegQueryInfoKeyA( HKEY hkey, LPSTR class, LPDWORD class_len, LPDW
if (status) goto done;
- len = 0; - if (class && class_len) len = *class_len; - RtlUnicodeToMultiByteN( class, len, class_len, - (WCHAR *)(buf_ptr + info->ClassOffset), info->ClassLength ); - if (len) + if (class && class_len && *class_len) { - if (*class_len + 1 > len) + DWORD len = *class_len; + RtlUnicodeToMultiByteN( class, len, class_len, + (WCHAR *)(buf_ptr + info->ClassOffset), info->ClassLength ); + if (*class_len == len) { status = STATUS_BUFFER_OVERFLOW; *class_len -= 1; } class[*class_len] = 0; } + else if (class_len) + RtlUnicodeToMultiByteSize( class_len, + (WCHAR *)(buf_ptr + info->ClassOffset), info->ClassLength ); } else status = STATUS_SUCCESS;
diff --git a/dlls/kernelbase/string.c b/dlls/kernelbase/string.c index 7bea47942e..668fd4fa37 100644 --- a/dlls/kernelbase/string.c +++ b/dlls/kernelbase/string.c @@ -1382,8 +1382,7 @@ INT WINAPI DECLSPEC_HOTPATCH LoadStringA(HINSTANCE instance, UINT resource_id, L
while (id--) p += *p + 1;
- if (buflen != 1) - RtlUnicodeToMultiByteN(buffer, buflen - 1, &retval, p + 1, *p * sizeof(WCHAR)); + RtlUnicodeToMultiByteN(buffer, buflen - 1, &retval, p + 1, *p * sizeof(WCHAR)); } buffer[retval] = 0; TRACE("returning %s\n", debugstr_a(buffer));