ntdll: Avoid memory allocations in RtlUpcaseUnicodeString functions.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2019-12-03 08:41:57 +01:00
parent 0e97fe86fd
commit b7fcb956ef
1 changed files with 49 additions and 43 deletions

View File

@ -1100,18 +1100,29 @@ NTSTATUS WINAPI RtlDowncaseUnicodeString(
* NOTES * NOTES
* writes terminating 0 * writes terminating 0
*/ */
NTSTATUS WINAPI RtlUpcaseUnicodeStringToAnsiString( STRING *dst, NTSTATUS WINAPI RtlUpcaseUnicodeStringToAnsiString( STRING *ansi,
const UNICODE_STRING *src, const UNICODE_STRING *uni,
BOOLEAN doalloc ) BOOLEAN doalloc )
{ {
NTSTATUS ret; NTSTATUS ret = STATUS_SUCCESS;
UNICODE_STRING upcase; DWORD len = RtlUnicodeStringToAnsiSize( uni );
if (!(ret = RtlUpcaseUnicodeString( &upcase, src, TRUE ))) ansi->Length = len - 1;
if (doalloc)
{ {
ret = RtlUnicodeStringToAnsiString( dst, &upcase, doalloc ); ansi->MaximumLength = len;
RtlFreeUnicodeString( &upcase ); if (!(ansi->Buffer = RtlAllocateHeap( GetProcessHeap(), 0, len )))
return STATUS_NO_MEMORY;
} }
else if (ansi->MaximumLength < len)
{
if (!ansi->MaximumLength) return STATUS_BUFFER_OVERFLOW;
ansi->Length = ansi->MaximumLength - 1;
ret = STATUS_BUFFER_OVERFLOW;
}
RtlUpcaseUnicodeToMultiByteN( ansi->Buffer, ansi->Length, NULL, uni->Buffer, uni->Length );
ansi->Buffer[ansi->Length] = 0;
return ret; return ret;
} }
@ -1128,18 +1139,29 @@ NTSTATUS WINAPI RtlUpcaseUnicodeStringToAnsiString( STRING *dst,
* NOTES * NOTES
* writes terminating 0 * writes terminating 0
*/ */
NTSTATUS WINAPI RtlUpcaseUnicodeStringToOemString( STRING *dst, NTSTATUS WINAPI RtlUpcaseUnicodeStringToOemString( STRING *oem,
const UNICODE_STRING *src, const UNICODE_STRING *uni,
BOOLEAN doalloc ) BOOLEAN doalloc )
{ {
NTSTATUS ret; NTSTATUS ret = STATUS_SUCCESS;
UNICODE_STRING upcase; DWORD len = RtlUnicodeStringToAnsiSize( uni );
if (!(ret = RtlUpcaseUnicodeString( &upcase, src, TRUE ))) oem->Length = len - 1;
if (doalloc)
{ {
ret = RtlUnicodeStringToOemString( dst, &upcase, doalloc ); oem->MaximumLength = len;
RtlFreeUnicodeString( &upcase ); if (!(oem->Buffer = RtlAllocateHeap( GetProcessHeap(), 0, len )))
return STATUS_NO_MEMORY;
} }
else if (oem->MaximumLength < len)
{
if (!oem->MaximumLength) return STATUS_BUFFER_OVERFLOW;
oem->Length = oem->MaximumLength - 1;
ret = STATUS_BUFFER_OVERFLOW;
}
RtlUpcaseUnicodeToOemN( oem->Buffer, oem->Length, NULL, uni->Buffer, uni->Length );
oem->Buffer[oem->Length] = 0;
return ret; return ret;
} }
@ -1160,38 +1182,22 @@ NTSTATUS WINAPI RtlUpcaseUnicodeStringToCountedOemString( STRING *oem,
const UNICODE_STRING *uni, const UNICODE_STRING *uni,
BOOLEAN doalloc ) BOOLEAN doalloc )
{ {
NTSTATUS ret; NTSTATUS ret = STATUS_SUCCESS;
UNICODE_STRING upcase; DWORD len = RtlUnicodeStringToOemSize( uni ) - 1;
WCHAR tmp[32];
upcase.Buffer = tmp; oem->Length = len;
upcase.MaximumLength = sizeof(tmp); if (doalloc)
ret = RtlUpcaseUnicodeString( &upcase, uni, FALSE );
if (ret == STATUS_BUFFER_OVERFLOW) ret = RtlUpcaseUnicodeString( &upcase, uni, TRUE );
if (!ret)
{ {
DWORD len = RtlUnicodeStringToOemSize( &upcase ) - 1; oem->MaximumLength = len;
oem->Length = len; if (!(oem->Buffer = RtlAllocateHeap( GetProcessHeap(), 0, len ))) return STATUS_NO_MEMORY;
if (doalloc)
{
oem->MaximumLength = len;
if (!(oem->Buffer = RtlAllocateHeap( GetProcessHeap(), 0, len )))
{
ret = STATUS_NO_MEMORY;
goto done;
}
}
else if (oem->MaximumLength < len)
{
ret = STATUS_BUFFER_OVERFLOW;
oem->Length = oem->MaximumLength;
if (!oem->MaximumLength) goto done;
}
RtlUnicodeToOemN( oem->Buffer, oem->Length, NULL, upcase.Buffer, upcase.Length );
done:
if (upcase.Buffer != tmp) RtlFreeUnicodeString( &upcase );
} }
else if (oem->MaximumLength < len)
{
ret = STATUS_BUFFER_OVERFLOW;
oem->Length = oem->MaximumLength;
if (!oem->MaximumLength) return ret;
}
RtlUpcaseUnicodeToOemN( oem->Buffer, oem->Length, NULL, uni->Buffer, uni->Length );
return ret; return ret;
} }