From 4e0ce779d777901c082d9501f43aabdfa3502451 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Gardou?= Date: Mon, 17 May 2021 12:07:26 +0200 Subject: [PATCH] [NTDLL_APITEST] Add some tests for RtlUnicodeToOemN CORE-17571 --- .../rostests/apitests/ntdll/CMakeLists.txt | 1 + .../apitests/ntdll/RtlUnicodeToOemN.c | 237 ++++++++++++++++++ modules/rostests/apitests/ntdll/testlist.c | 2 + 3 files changed, 240 insertions(+) create mode 100644 modules/rostests/apitests/ntdll/RtlUnicodeToOemN.c diff --git a/modules/rostests/apitests/ntdll/CMakeLists.txt b/modules/rostests/apitests/ntdll/CMakeLists.txt index 684990e2df5..ef5f6a61302 100644 --- a/modules/rostests/apitests/ntdll/CMakeLists.txt +++ b/modules/rostests/apitests/ntdll/CMakeLists.txt @@ -81,6 +81,7 @@ list(APPEND SOURCE RtlReAllocateHeap.c RtlUnicodeStringToAnsiString.c RtlUnicodeStringToCountedOemString.c + RtlUnicodeToOemN.c RtlUpcaseUnicodeStringToCountedOemString.c RtlValidateUnicodeString.c RtlxUnicodeStringToAnsiSize.c diff --git a/modules/rostests/apitests/ntdll/RtlUnicodeToOemN.c b/modules/rostests/apitests/ntdll/RtlUnicodeToOemN.c new file mode 100644 index 00000000000..ff20e9a7b82 --- /dev/null +++ b/modules/rostests/apitests/ntdll/RtlUnicodeToOemN.c @@ -0,0 +1,237 @@ +/* + * PROJECT: ReactOS API tests + * LICENSE: 0BSD (https://spdx.org/licenses/0BSD.html) + * PURPOSE: Test for RtlUnicodeToOemN + * COPYRIGHT: Copyright 2021 Jérôme Gardou + */ + +#include "precomp.h" + +static const struct +{ + ULONG AnsiCp; + ULONG OemCp; + struct + { + LPCWSTR StrW; + NTSTATUS Status; + ULONG ReturnedSize; + LPCSTR StrOem; + } Test[10]; +} TestData[] = +{ + { + 1252, 1252, /* Western SBCS */ + { + { + L"ABCDEF", + STATUS_SUCCESS, + 6, + "ABCDEF" + }, + { + L"ABCDEF", + STATUS_SUCCESS, + 6, + "ABCDEF\xAA\xAA\xAA" + }, + { + L"ABCDEF", + STATUS_BUFFER_OVERFLOW, + 3, + "ABC" + }, + { + L"\u30c7\u30b9\u30af\u30c8\u30c3\u30d7", + STATUS_SUCCESS, + 6, + "??????" + }, + { + L"\u30c7\u30b9\u30af\u30c8\u30c3\u30d7", + STATUS_BUFFER_OVERFLOW, + 3, + "???" + }, + } + }, + { + 1252, 932, /* Western SBCS - Modified SJIS */ + { + { + L"\u30c7\u30b9\u30af\u30c8\u30c3\u30d7", + STATUS_SUCCESS, + 12, + "\x83\x66\x83\x58\x83\x4e\x83\x67\x83\x62\x83\x76" + }, + { + L"\u30c7\u30b9\u30af\u30c8\u30c3\u30d7", + STATUS_SUCCESS, + 12, + "\x83\x66\x83\x58\x83\x4e\x83\x67\x83\x62\x83\x76\xAA\xAA\xAA" + }, + } + }, + { + 932, 1252, /* Modified SJIS - Western SBCS */ + { + { + L"\u30c7\u30b9\u30af\u30c8\u30c3\u30d7", + STATUS_SUCCESS, + 6, + "??????" + }, + { + L"\u30c7\u30b9\u30afABC", + STATUS_SUCCESS, + 6, + "???ABC" + }, + { + L"\u30c7\u30b9\u30af\u30c8\u30c3\u30d7", + STATUS_BUFFER_OVERFLOW, + 3, + "???" + }, + } + }, + { + 932, 932, /* Modified SJIS - Modified SJIS */ + { + { + L"\u30c7\u30b9\u30af\u30c8\u30c3\u30d7", + STATUS_SUCCESS, + 12, + "\x83\x66\x83\x58\x83\x4e\x83\x67\x83\x62\x83\x76" + } + } + }, +}; + +START_TEST(RtlUnicodeToOemN) +{ + ULONG Length; + LPSTR StrOem; + ULONG ResultSize; + NTSTATUS Status; + CHAR OemBuffer[4]; + + /* Basic things */ + Status = RtlUnicodeToOemN(NULL, 0, NULL, NULL, 0); + ok_ntstatus(Status, STATUS_SUCCESS); + + Status = RtlUnicodeToOemN(NULL, 0, NULL, L"ABCDEF", 0); + ok_ntstatus(Status, STATUS_SUCCESS); + + Status = RtlUnicodeToOemN(NULL, 0, NULL, NULL, 2); + ok_ntstatus(Status, STATUS_BUFFER_OVERFLOW); + + Status = RtlUnicodeToOemN(NULL, 0, NULL, L"A", 2); + ok_ntstatus(Status, STATUS_BUFFER_OVERFLOW); + + Status = RtlUnicodeToOemN(NULL, 0, NULL, L"A", 2); + ok_ntstatus(Status, STATUS_BUFFER_OVERFLOW); + + StartSeh() + Status = RtlUnicodeToOemN(NULL, 1, NULL, L"A", 2); + EndSeh(STATUS_ACCESS_VIOLATION) + + OemBuffer[0] = 0xAA; + OemBuffer[1] = 0xAA; + Status = RtlUnicodeToOemN(OemBuffer, 1, NULL, L"A", 2); + ok_ntstatus(Status, STATUS_SUCCESS); + ok_char(OemBuffer[0], 'A'); + ok_char(OemBuffer[1], (CHAR)0xAA); + + OemBuffer[0] = 0xAA; + OemBuffer[1] = 0xAA; + Status = RtlUnicodeToOemN(OemBuffer, 1, NULL, L"AB", 4); + ok_ntstatus(Status, STATUS_BUFFER_OVERFLOW); + ok_char(OemBuffer[0], 'A'); + ok_char(OemBuffer[1], (CHAR)0xAA); + + OemBuffer[0] = 0xAA; + OemBuffer[1] = 0xAA; + Status = RtlUnicodeToOemN(OemBuffer, 2, NULL, L"A", 4); + ok_ntstatus(Status, STATUS_SUCCESS); + ok_char(OemBuffer[0], 'A'); + ok_char(OemBuffer[1], '\0'); + + /* RtlUnicodeToOemN doesn't care about string termination */ + OemBuffer[0] = 0xAA; + OemBuffer[1] = 0xAA; + Status = RtlUnicodeToOemN(OemBuffer, 1, NULL, L"A", 4); + ok_ntstatus(Status, STATUS_BUFFER_OVERFLOW); + ok_char(OemBuffer[0], 'A'); + ok_char(OemBuffer[1], (CHAR)0xAA); + + OemBuffer[0] = 0xAA; + OemBuffer[1] = 0xAA; + OemBuffer[2] = 0xAA; + OemBuffer[3] = 0xAA; + Status = RtlUnicodeToOemN(OemBuffer, 4, NULL, L"A\0B", 8); + ok_ntstatus(Status, STATUS_SUCCESS); + ok_char(OemBuffer[0], 'A'); + ok_char(OemBuffer[1], '\0'); + ok_char(OemBuffer[2], 'B'); + ok_char(OemBuffer[3], '\0'); + + /* Odd Unicode buffer size */ + OemBuffer[0] = 0xAA; + OemBuffer[1] = 0xAA; + OemBuffer[2] = 0xAA; + OemBuffer[3] = 0xAA; + Status = RtlUnicodeToOemN(OemBuffer, 2, NULL, L"AB", 5); + ok_ntstatus(Status, STATUS_SUCCESS); + ok_char(OemBuffer[0], 'A'); + ok_char(OemBuffer[1], 'B'); + ok_char(OemBuffer[2], (CHAR)0xAA); + ok_char(OemBuffer[3], (CHAR)0xAA); + + /* Odd Unicode buffer size */ + OemBuffer[0] = 0xAA; + OemBuffer[1] = 0xAA; + OemBuffer[2] = 0xAA; + OemBuffer[3] = 0xAA; + Status = RtlUnicodeToOemN(OemBuffer, 3, NULL, L"AB", 5); + ok_ntstatus(Status, STATUS_SUCCESS); + ok_char(OemBuffer[0], 'A'); + ok_char(OemBuffer[1], 'B'); + ok_char(OemBuffer[2], (CHAR)0xAA); + ok_char(OemBuffer[3], (CHAR)0xAA); + + for (int i = 0; i < _countof(TestData); i++) + { + SetupLocale(TestData[i].AnsiCp, TestData[i].OemCp, -1); + + for (int j = 0; TestData[i].Test[j].StrW != NULL; j++) + { + Length = strlen(TestData[i].Test[j].StrOem); + StrOem = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length + 1); + + memset(StrOem, 0xAA, Length + 1); + ResultSize = 0x0BADF00D; + + Status = RtlUnicodeToOemN(StrOem, + Length, + &ResultSize, + TestData[i].Test[j].StrW, + wcslen(TestData[i].Test[j].StrW) * sizeof(WCHAR)); + + ok_ntstatus(Status, TestData[i].Test[j].Status); + ok_long(ResultSize, TestData[i].Test[j].ReturnedSize); + for (int k = 0; k < ResultSize; k++) + { + ok(StrOem[k] == TestData[i].Test[j].StrOem[k], + "Wrong char \\x%02x, expected TestData[%u].Test[%u].StrOem[%u] (\\x%02x)\n", + StrOem[k], i, j, k, TestData[i].Test[j].StrOem[k]); + } + for (int k = ResultSize; k < (Length + 1); k++) + { + ok_char(StrOem[k], (CHAR)0xAA); + } + + RtlFreeHeap(RtlGetProcessHeap(), 0, StrOem); + } + } +} diff --git a/modules/rostests/apitests/ntdll/testlist.c b/modules/rostests/apitests/ntdll/testlist.c index 5d4b00b0cce..5a56ec6e987 100644 --- a/modules/rostests/apitests/ntdll/testlist.c +++ b/modules/rostests/apitests/ntdll/testlist.c @@ -77,6 +77,7 @@ extern void func_RtlQueryTimeZoneInformation(void); extern void func_RtlReAllocateHeap(void); extern void func_RtlUnicodeStringToAnsiString(void); extern void func_RtlUnicodeStringToCountedOemString(void); +extern void func_RtlUnicodeToOemN(void); extern void func_RtlUpcaseUnicodeStringToCountedOemString(void); extern void func_RtlValidateUnicodeString(void); extern void func_RtlxUnicodeStringToAnsiSize(void); @@ -162,6 +163,7 @@ const struct test winetest_testlist[] = { "RtlUnicodeStringToAnsiString", func_RtlUnicodeStringToAnsiString }, { "RtlUnicodeStringToCountedOemString", func_RtlUnicodeStringToCountedOemString }, { "RtlUnicodeStringToOemSize", func_RtlxUnicodeStringToOemSize }, + { "RtlUnicodeToOemN", func_RtlUnicodeToOemN }, { "RtlUpcaseUnicodeStringToCountedOemString", func_RtlUpcaseUnicodeStringToCountedOemString }, { "RtlValidateUnicodeString", func_RtlValidateUnicodeString }, { "StackOverflow", func_StackOverflow },