kernelbase: Fix assumptions about 0-size output buffer in ntdll Unicode conversion functions.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2019-12-03 08:30:36 +01:00
parent 5536df1ee1
commit 94d2b4742c
3 changed files with 28 additions and 12 deletions

View File

@ -292,10 +292,25 @@ DWORD file_name_WtoA( LPCWSTR src, INT srclen, LPSTR dest, INT destlen )
DWORD ret; DWORD ret;
if (srclen < 0) srclen = lstrlenW( src ) + 1; if (srclen < 0) srclen = lstrlenW( src ) + 1;
if (oem_file_apis) if (!destlen)
RtlUnicodeToOemN( dest, destlen, &ret, src, srclen * sizeof(WCHAR) ); {
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 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; return ret;
} }

View File

@ -915,7 +915,7 @@ LSTATUS WINAPI RegQueryInfoKeyA( HKEY hkey, LPSTR class, LPDWORD class_len, LPDW
NTSTATUS status; NTSTATUS status;
char buffer[256], *buf_ptr = buffer; char buffer[256], *buf_ptr = buffer;
KEY_FULL_INFORMATION *info = (KEY_FULL_INFORMATION *)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, 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 ); 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; if (status) goto done;
len = 0; if (class && class_len && *class_len)
if (class && class_len) len = *class_len;
RtlUnicodeToMultiByteN( class, len, class_len,
(WCHAR *)(buf_ptr + info->ClassOffset), info->ClassLength );
if (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; status = STATUS_BUFFER_OVERFLOW;
*class_len -= 1; *class_len -= 1;
} }
class[*class_len] = 0; class[*class_len] = 0;
} }
else if (class_len)
RtlUnicodeToMultiByteSize( class_len,
(WCHAR *)(buf_ptr + info->ClassOffset), info->ClassLength );
} }
else status = STATUS_SUCCESS; else status = STATUS_SUCCESS;

View File

@ -1382,8 +1382,7 @@ INT WINAPI DECLSPEC_HOTPATCH LoadStringA(HINSTANCE instance, UINT resource_id, L
while (id--) p += *p + 1; 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; buffer[retval] = 0;
TRACE("returning %s\n", debugstr_a(buffer)); TRACE("returning %s\n", debugstr_a(buffer));