summaryrefslogtreecommitdiff
path: root/src/pal/tests
diff options
context:
space:
mode:
authorWilliam Godbe <william.godbe@comcast.net>2016-01-21 15:14:48 -0800
committerwtgodbe <wigodbe@microsoft.com>2016-03-18 11:50:02 -0700
commiteef4ca509b156597cea92d689672dacbac2cb7e1 (patch)
tree1a0e6d250fc5d705f33dd02b7e503079415ecdf1 /src/pal/tests
parent1a9eb1c5f4d9f257f3f96ef5205a0eb1a23395c3 (diff)
downloadcoreclr-eef4ca509b156597cea92d689672dacbac2cb7e1.tar.gz
coreclr-eef4ca509b156597cea92d689672dacbac2cb7e1.tar.bz2
coreclr-eef4ca509b156597cea92d689672dacbac2cb7e1.zip
Ported managed Utf8/Unicode encoder/decoder to C++ for usage in PAL
Diffstat (limited to 'src/pal/tests')
-rw-r--r--src/pal/tests/palsuite/locale_info/MultiByteToWideChar/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test4/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test4/test4.c230
-rw-r--r--src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test4/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/locale_info/WideCharToMultiByte/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test1/test1.c5
-rw-r--r--src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test2/test2.c5
-rw-r--r--src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test3/test3.c5
-rw-r--r--src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test5/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test5/test5.c154
-rw-r--r--src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test5/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/paltestlist.txt5
-rw-r--r--src/pal/tests/palsuite/paltestlist_to_be_reviewed.txt3
13 files changed, 455 insertions, 20 deletions
diff --git a/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/CMakeLists.txt
index 1962ade358..0b8ae6062e 100644
--- a/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/CMakeLists.txt
+++ b/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/CMakeLists.txt
@@ -3,4 +3,4 @@ cmake_minimum_required(VERSION 2.8.12.2)
add_subdirectory(test1)
add_subdirectory(test2)
add_subdirectory(test3)
-
+add_subdirectory(test4)
diff --git a/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test4/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test4/CMakeLists.txt
new file mode 100644
index 0000000000..3d167dff7c
--- /dev/null
+++ b/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test4/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test4.c
+)
+
+add_executable(paltest_multibytetowidechar_test4
+ ${SOURCES}
+)
+
+add_dependencies(paltest_multibytetowidechar_test4 coreclrpal)
+
+target_link_libraries(paltest_multibytetowidechar_test4
+ pthread
+ m
+ coreclrpal
+) \ No newline at end of file
diff --git a/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test4/test4.c b/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test4/test4.c
new file mode 100644
index 0000000000..2ba606cf35
--- /dev/null
+++ b/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test4/test4.c
@@ -0,0 +1,230 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*============================================================================
+**
+** Source: test4.c
+**
+** Purpose: Tests MultiByteToWideChar with a UTF-8 encoding
+**
+**
+**==========================================================================*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+ int ret;
+ int ret2;
+
+ if (PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+ const char * const utf8Strings[] =
+ {
+ // Correct strings
+
+ // Empty string
+ "",
+ // 1 byte encoded 1 character long string
+ "A",
+ // 2 byte encoded 1 character long string
+ "\xC2\x80",
+ // 3 byte encoded 1 character long string
+ "\xE0\xA0\x80",
+ // 1 byte encoded characters only
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
+ // valid 2 byte encoded characters only
+ "\xC2\x80\xC3\xBF\xC7\x81\xDF\xBF",
+ // valid 3 byte encoded characters only
+ "\xE0\xA0\x80\xE1\xB6\x88\xE1\x80\x80\xEF\xBF\xBF",
+ // 1 byte and 2 byte encoded characters interleaved 1:1 starting and ending with 1 byte char
+ "\x41\xC2\x80\x42\xC3\xBF\x43\xC7\x81\x44\xDF\xBF\x45",
+ // 1 byte and 2 byte encoded characters interleaved 1:1 starting with 1 byte char, ending with 2 byte one
+ "\x41\xC2\x80\x42\xC3\xBF\x43\xC7\x81\x44\xDF\xBF",
+ // 1 byte and 2 byte encoded characters interleaved 1:1 starting with 2 byte char, ending with 1 byte one
+ "\xC2\x80\x42\xC3\xBF\x43\xC7\x81\x44\xDF\xBF\x45",
+ // 1 byte and 2 byte encoded characters interleaved 1:1 starting and ending with 2 byte char
+ "\xC2\x80\x42\xC3\xBF\x43\xC7\x81\x44\xDF\xBF",
+ // 1 byte and 2 byte encoded characters interleaved 2:2 starting and ending with 1 byte char
+ "\x41\x42\xC2\x80\xC3\xBF\x43\x44\xC7\x81\xDF\xBF\x45\x46",
+ // 1 byte and 2 byte encoded characters interleaved 2:2 starting with 1 byte char, ending with 2 byte one
+ "\x41\x42\xC2\x80\xC3\xBF\x43\x44\xC7\x81\xDF\xBF",
+ // 1 byte and 2 byte encoded characters interleaved 2:2 starting with 2 byte char, ending with 1 byte one
+ "\xC2\x80\xC3\xBF\x43\x44\xC7\x81\xDF\xBF\x45\x46",
+ // 1 byte and 2 byte encoded characters interleaved 2:2 starting and ending with 2 byte char
+ "\xC2\x80\xC3\xBF\x43\x44\xC7\x81\xDF\xBF",
+ // surrogates
+ "\xF0\x90\x80\x80\xF0\x90\x89\x80\xF3\x80\x8E\xB0\xF4\x8F\xBF\xBF",
+
+ // Strings with errors
+ // Incomplete 2 byte encoded character 1 byte missing standalone
+ "\xC2",
+ // Incomplete 3 byte encoded character 1 byte missing standalone
+ "\xE0\xA0",
+ // Incomplete 3 byte encoded character 2 bytes missing standalone
+ "\xE0",
+ // Incomplete surrogate character 1 byte missing standalone
+ "\xF0\x90\x80",
+ // Incomplete surrogate character 2 bytes missing standalone
+ "\xF0\x90",
+ // Incomplete surrogate character 3 bytes missing standalone
+ "\xF0",
+ // Trailing byte with no lead byte standalone
+ "\x80",
+ // Incomplete 2 byte encoded character 1 byte missing between 1 byte chars
+ "\x41\xC2\x42",
+ // Incomplete 3 byte encoded character 1 byte missing between 1 byte chars
+ "\x41\xE0\xA0\x42",
+ // Incomplete 3 byte encoded character 2 bytes missing between 1 byte chars
+ "\x41\xE0\x42",
+ // Trailing byte with no lead byte between 1 byte chars
+ "\x41\x80\x42",
+ // Incomplete 2 byte encoded character 1 byte missing before 1 byte char
+ "\xC2\x42",
+ // Incomplete 3 byte encoded character 1 byte missing before 1 byte char
+ "\xE0\xA0\x42",
+ // Incomplete 3 byte encoded character 2 bytes missing before 1 byte char
+ "\xE0\x42",
+ // Trailing byte with no lead byte before 1 byte char
+ "\x80\x42",
+ // Incomplete 2 byte encoded character 1 byte missing after 1 byte char
+ "\x41\xC2",
+ // Incomplete 3 byte encoded character 1 byte missing after 1 byte char
+ "\x41\xE0\xA0",
+ // Incomplete 3 byte encoded character 2 bytes missing after 1 byte char
+ "\x41\xE0",
+ // Trailing byte with no lead byte after 1 byte char
+ "\x41\x80",
+ // Incomplete 2 byte encoded character 1 byte missing between 2 byte chars
+ "\xC2\x80\xC2\xC3\xBF",
+ // Incomplete 3 byte encoded character 1 byte missing between 2 byte chars
+ "\xC2\x80\xE0\xA0\xC3\xBF",
+ // Incomplete 3 byte encoded character 2 bytes missing between 2 byte chars
+ "\xC2\x80\xE0\xC3\xBF",
+ // Trailing byte with no lead byte between 2 byte chars
+ "\xC2\x80\x80\xC3\xBF",
+ // 2 byte encoded character in non-shortest form encodings (these are not allowed)
+ "\xC0\x80",
+ // 3 byte encoded character in non-shortest form encodings (these are not allowed)
+ "\xE0\x80\x80",
+ // 4 byte encoded character in non-shortest form encodings (these are not allowed)
+ "\xF0\x80\x80\x80",
+ };
+
+ const WCHAR * const unicodeStrings[] =
+ {
+ // Empty string
+ W(""),
+ // 1 byte encoded 1 character long string
+ W("A"),
+ // 2 byte encoded 1 character long string
+ W("\x0080"),
+ // 3 byte encoded 1 character long string
+ W("\x0800"),
+ // 1 byte encoded characters only
+ W("ABCDEFGHIJKLMNOPQRSTUVWXYZ"),
+ // 2 byte encoded characters only
+ W("\x0080\x00FF\x01C1\x07FF"),
+ // valid 3 byte encoded characters only
+ W("\x0800\x1D88\x1000\xFFFF"),
+ // 1 byte and 2 byte encoded characters interleaved 1:1 starting and ending with 1 byte char
+ W("\x0041\x0080\x0042\x00FF\x0043\x01C1\x0044\x07FF\x0045"),
+ // 1 byte and 2 byte encoded characters interleaved 1:1 starting with 1 byte char, ending with 2 byte one
+ W("\x0041\x0080\x0042\x00FF\x0043\x01C1\x0044\x07FF"),
+ // 1 byte and 2 byte encoded characters interleaved 1:1 starting with 2 byte char, ending with 1 byte one
+ W("\x0080\x0042\x00FF\x0043\x01C1\x0044\x07FF\x0045"),
+ // 1 byte and 2 byte encoded characters interleaved 1:1 starting and ending with 2 byte char
+ W("\x0080\x0042\x00FF\x0043\x01C1\x0044\x07FF"),
+ // 1 byte and 2 byte encoded characters interleaved 2:2 starting and ending with 1 byte char
+ W("\x0041\x0042\x0080\x00FF\x0043\x0044\x01C1\x07FF\x0045\x0046"),
+ // 1 byte and 2 byte encoded characters interleaved 2:2 starting with 1 byte char, ending with 2 byte one
+ W("\x0041\x0042\x0080\x00FF\x0043\x0044\x01C1\x07FF"),
+ // 1 byte and 2 byte encoded characters interleaved 2:2 starting with 2 byte char, ending with 1 byte one
+ W("\x0080\x00FF\x0043\x0044\x01C1\x07FF\x0045\x0046"),
+ // 1 byte and 2 byte encoded characters interleaved 2:2 starting and ending with 2 byte char
+ W("\x0080\x00FF\x0043\x0044\x01C1\x07FF"),
+ // surrogates
+ W("\xD800\xDC00\xD800\xDE40\xDAC0\xDFB0\xDBFF\xDFFF"),
+
+ // Strings with errors
+ // Incomplete 2 byte encoded character standalone
+ W(""),
+ // Incomplete 3 byte encoded character 1 byte missing standalone
+ W(""),
+ // Incomplete 3 byte encoded character 2 bytes missing standalone
+ W(""),
+ // Incomplete surrogate character 1 byte missing standalone
+ W(""),
+ // Incomplete surrogate character 2 bytes missing standalone
+ W(""),
+ // Incomplete surrogate character 3 bytes missing standalone
+ W(""),
+ // Trailing byte with no lead byte standalone
+ W(""),
+ // Incomplete 2 byte encoded character 1 byte missing between 1 byte chars
+ W("\x0041\x0042"),
+ // Incomplete 3 byte encoded character 1 byte missing between 1 byte chars
+ W("\x0041\x0042"),
+ // Incomplete 3 byte encoded character 2 bytes missing between 1 byte chars
+ W("\x0041\x0042"),
+ // Trailing byte with no lead byte between 1 byte chars
+ W("\x0041\x0042"),
+ // Incomplete 2 byte encoded character 1 byte missing before 1 byte char
+ W("\x0042"),
+ // Incomplete 3 byte encoded character 1 byte missing before 1 byte char
+ W("\x0042"),
+ // Incomplete 3 byte encoded character 2 bytes missing before 1 byte char
+ W("\x0042"),
+ // Trailing byte with no lead byte before 1 byte char
+ W("\x0042"),
+ // Incomplete 2 byte encoded character 1 byte missing after 1 byte char
+ W("\x0041"),
+ // Incomplete 3 byte encoded character 1 byte missing after 1 byte char
+ W("\x0041"),
+ // Incomplete 3 byte encoded character 2 bytes missing after 1 byte char
+ W("\x0041"),
+ // Trailing byte with no lead byte after 1 byte char
+ W("\x0041"),
+ // Incomplete 2 byte encoded character 1 byte missing between 2 byte chars
+ W("\x0080\x00FF"),
+ // Incomplete 3 byte encoded character 1 byte missing between 2 byte chars
+ W("\x0080\x00FF"),
+ // Incomplete 3 byte encoded character 2 bytes missing between 2 byte chars
+ W("\x0080\x00FF"),
+ // Trailing byte with no lead byte between 2 byte chars
+ W("\x0080\x00FF"),
+ // 2 byte encoded character in non-shortest form encodings (these are not allowed)
+ W(""),
+ // 3 byte encoded character in non-shortest form encodings (these are not allowed)
+ W(""),
+ // 4 byte encoded character in non-shortest form encodings (these are not allowed)
+ W(""),
+ };
+
+ for (int i = 0; i < (sizeof(utf8Strings) / sizeof(utf8Strings[0])); i++)
+ {
+ ret = MultiByteToWideChar(CP_UTF8, 0, utf8Strings[i], -1, NULL, 0);
+ WCHAR* wideBuffer = malloc(ret * sizeof(WCHAR));
+ ret2 = MultiByteToWideChar(CP_UTF8, 0, utf8Strings[i], -1, wideBuffer, ret);
+ if (ret != ret2)
+ {
+ Fail("MultiByteToWideChar string %d: returned different string length for empty and real dest buffers!\n"
+ "Got %d for the empty one, %d for real one.\n", i, ret2, ret);
+ }
+
+ if (wcscmp(wideBuffer, unicodeStrings[i]) != 0)
+ {
+ Fail("MultiByteToWideChar string %d: the resulting string doesn't match the expected one!\n", i);
+ }
+
+ free(wideBuffer);
+ }
+
+ PAL_Terminate();
+
+ return PASS;
+} \ No newline at end of file
diff --git a/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test4/testinfo.dat b/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test4/testinfo.dat
new file mode 100644
index 0000000000..e95f413904
--- /dev/null
+++ b/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test4/testinfo.dat
@@ -0,0 +1,13 @@
+#
+# Copyright (c) Microsoft Corporation. All rights reserved.
+#
+
+Version = 1.0
+Section = Locale Information
+Function = MultiByteToWideChar
+Name = Test #4 for MultiByteToWideChar
+TYPE = DEFAULT
+EXE1 = test4
+Description
+=Tests MultiByteToWideChar with UTF-8 encoded strings
+=containing various corner cases \ No newline at end of file
diff --git a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/CMakeLists.txt
index a3847f8ca9..dc5d5131ec 100644
--- a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/CMakeLists.txt
+++ b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/CMakeLists.txt
@@ -4,4 +4,4 @@ add_subdirectory(test1)
add_subdirectory(test2)
add_subdirectory(test3)
add_subdirectory(test4)
-
+add_subdirectory(test5)
diff --git a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test1/test1.c b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test1/test1.c
index f04a7aeca0..cd763f33be 100644
--- a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test1/test1.c
+++ b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test1/test1.c
@@ -27,11 +27,6 @@ int __cdecl main(int argc, char *argv[])
/* These codepages are currently supported by the PAL */
int codePages[] ={
CP_ACP,
-// 932,
- 949,
- 950,
- 1252,
- 1258,
CP_UTF8
};
diff --git a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test2/test2.c b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test2/test2.c
index 372037b686..f5d40ae903 100644
--- a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test2/test2.c
+++ b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test2/test2.c
@@ -27,11 +27,6 @@ int __cdecl main(int argc, char *argv[])
/* These codepages are currently supported by the PAL */
int codePages[] ={
CP_ACP,
-// 932,
- 949,
- 950,
- 1252,
- 1258,
CP_UTF8
};
diff --git a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test3/test3.c b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test3/test3.c
index 7f0936ade9..ecd26addb4 100644
--- a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test3/test3.c
+++ b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test3/test3.c
@@ -29,11 +29,6 @@ int __cdecl main(int argc, char *argv[])
/* These codepages are currently supported by the PAL */
int codePages[] ={
CP_ACP,
-// 932,
- 949,
- 950,
- 1252,
- 1258,
CP_UTF8
};
diff --git a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test5/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test5/CMakeLists.txt
new file mode 100644
index 0000000000..6ca2a628bf
--- /dev/null
+++ b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test5/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test5.c
+)
+
+add_executable(paltest_widechartomultibyte_test5
+ ${SOURCES}
+)
+
+add_dependencies(paltest_widechartomultibyte_test5 coreclrpal)
+
+target_link_libraries(paltest_widechartomultibyte_test5
+ pthread
+ m
+ coreclrpal
+) \ No newline at end of file
diff --git a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test5/test5.c b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test5/test5.c
new file mode 100644
index 0000000000..3ca0d90d0f
--- /dev/null
+++ b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test5/test5.c
@@ -0,0 +1,154 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*============================================================================
+**
+** Source: test4.c
+**
+** Purpose: Tests WideCharMultiByte with UTF-8 encoding
+**
+**
+**==========================================================================*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+ int ret;
+ int ret2;
+
+ if (PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+ const WCHAR * const unicodeStrings[] =
+ {
+ // Correct strings
+
+ // Empty string
+ W(""),
+ // 1 byte encoded 1 character long string
+ W("A"),
+ // 2 byte encoded 1 character long string
+ W("\x0080"),
+ // 3 byte encoded 1 character long string
+ W("\x0800"),
+ // 1 byte encoded characters only
+ W("ABCDEFGHIJKLMNOPQRSTUVWXYZ"),
+ // 2 byte encoded characters only
+ W("\x0080\x00FF\x01C1\x07FF"),
+ // valid 3 byte encoded characters only
+ W("\x0800\x1D88\x1000\xFFFF"),
+ // 1 byte and 2 byte encoded characters interleaved 1:1 starting and ending with 1 byte char
+ W("\x0041\x0080\x0042\x00FF\x0043\x01C1\x0044\x07FF\x0045"),
+ // 1 byte and 2 byte encoded characters interleaved 1:1 starting with 1 byte char, ending with 2 byte one
+ W("\x0041\x0080\x0042\x00FF\x0043\x01C1\x0044\x07FF"),
+ // 1 byte and 2 byte encoded characters interleaved 1:1 starting with 2 byte char, ending with 1 byte one
+ W("\x0080\x0042\x00FF\x0043\x01C1\x0044\x07FF\x0045"),
+ // 1 byte and 2 byte encoded characters interleaved 1:1 starting and ending with 2 byte char
+ W("\x0080\x0042\x00FF\x0043\x01C1\x0044\x07FF"),
+ // 1 byte and 2 byte encoded characters interleaved 2:2 starting and ending with 1 byte char
+ W("\x0041\x0042\x0080\x00FF\x0043\x0044\x01C1\x07FF\x0045\x0046"),
+ // 1 byte and 2 byte encoded characters interleaved 2:2 starting with 1 byte char, ending with 2 byte one
+ W("\x0041\x0042\x0080\x00FF\x0043\x0044\x01C1\x07FF"),
+ // 1 byte and 2 byte encoded characters interleaved 2:2 starting with 2 byte char, ending with 1 byte one
+ W("\x0080\x00FF\x0043\x0044\x01C1\x07FF\x0045\x0046"),
+ // 1 byte and 2 byte encoded characters interleaved 2:2 starting and ending with 2 byte char
+ W("\x0080\x00FF\x0043\x0044\x01C1\x07FF"),
+ // Surrogates
+ W("\xD800\xDC00\xD800\xDE40\xDAC0\xDFB0\xDBFF\xDFFF"),
+
+ // Strings with errors
+
+ // Single high surrogate
+ W("\xD800"),
+ // Single low surrogate
+ W("\xDC00"),
+ // Character followed by single high surrogate
+ W("\x0041\xD800"),
+ // Character followed by single low surrogate
+ W("\x0041\xDC00"),
+ // Single high surrogate between two characters
+ W("\x0041\xD800\x0042"),
+ // Single low surrogate between two characters
+ W("\x0041\xDC00\x0042"),
+ };
+
+ const char * const utf8Strings[] =
+ {
+ // Correct strings
+
+ // Empty string
+ "",
+ // 1 byte encoded 1 character long string
+ "A",
+ // 2 byte encoded 1 character long string
+ "\xC2\x80",
+ // 3 byte encoded 1 character long string
+ "\xE0\xA0\x80",
+ // 1 byte encoded characters only
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
+ // valid 2 byte encoded characters only
+ "\xC2\x80\xC3\xBF\xC7\x81\xDF\xBF",
+ // valid 3 byte encoded characters only
+ "\xE0\xA0\x80\xE1\xB6\x88\xE1\x80\x80\xEF\xBF\xBF",
+ // 1 byte and 2 byte encoded characters interleaved 1:1 starting and ending with 1 byte char
+ "\x41\xC2\x80\x42\xC3\xBF\x43\xC7\x81\x44\xDF\xBF\x45",
+ // 1 byte and 2 byte encoded characters interleaved 1:1 starting with 1 byte char, ending with 2 byte one
+ "\x41\xC2\x80\x42\xC3\xBF\x43\xC7\x81\x44\xDF\xBF",
+ // 1 byte and 2 byte encoded characters interleaved 1:1 starting with 2 byte char, ending with 1 byte one
+ "\xC2\x80\x42\xC3\xBF\x43\xC7\x81\x44\xDF\xBF\x45",
+ // 1 byte and 2 byte encoded characters interleaved 1:1 starting and ending with 2 byte char
+ "\xC2\x80\x42\xC3\xBF\x43\xC7\x81\x44\xDF\xBF",
+ // 1 byte and 2 byte encoded characters interleaved 2:2 starting and ending with 1 byte char
+ "\x41\x42\xC2\x80\xC3\xBF\x43\x44\xC7\x81\xDF\xBF\x45\x46",
+ // 1 byte and 2 byte encoded characters interleaved 2:2 starting with 1 byte char, ending with 2 byte one
+ "\x41\x42\xC2\x80\xC3\xBF\x43\x44\xC7\x81\xDF\xBF",
+ // 1 byte and 2 byte encoded characters interleaved 2:2 starting with 2 byte char, ending with 1 byte one
+ "\xC2\x80\xC3\xBF\x43\x44\xC7\x81\xDF\xBF\x45\x46",
+ // 1 byte and 2 byte encoded characters interleaved 2:2 starting and ending with 2 byte char
+ "\xC2\x80\xC3\xBF\x43\x44\xC7\x81\xDF\xBF",
+ // Surrogates
+ "\xF0\x90\x80\x80\xF0\x90\x89\x80\xF3\x80\x8E\xB0\xF4\x8F\xBF\xBF",
+
+ // Strings with errors
+
+ // Single high surrogate
+ "\xEF\xBF\xBD",
+ // Single low surrogate
+ "\xEF\xBF\xBD",
+ // Character followed by single high surrogate
+ "\x41\xEF\xBF\xBD",
+ // Character followed by single low surrogate
+ "\x41\xEF\xBF\xBD",
+ // Single high surrogate between two characters
+ "\x41\xEF\xBF\xBD\x42",
+ // Single low surrogate between two characters
+ "\x41\xEF\xBF\xBD\x42",
+ };
+
+ for (int i = 0; i < (sizeof(unicodeStrings) / sizeof(unicodeStrings[0])); i++)
+ {
+ ret = WideCharToMultiByte(CP_UTF8, 0, unicodeStrings[i], -1, NULL, 0, NULL, NULL);
+ CHAR* utf8Buffer = malloc(ret * sizeof(CHAR));
+ ret2 = WideCharToMultiByte(CP_UTF8, 0, unicodeStrings[i], -1, utf8Buffer, ret, NULL, NULL);
+ if (ret != ret2)
+ {
+ Fail("WideCharToMultiByte string %d: returned different string length for empty and real dest buffers!\n"
+ "Got %d for the empty one, %d for real one.\n", i, ret2, ret);
+ }
+
+ if (strcmp(utf8Buffer, utf8Strings[i]) != 0)
+ {
+ Fail("WideCharToMultiByte string %d: the resulting string doesn't match the expected one!\n", i);
+ }
+
+ free(utf8Buffer);
+ }
+
+ PAL_Terminate();
+
+ return PASS;
+} \ No newline at end of file
diff --git a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test5/testinfo.dat b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test5/testinfo.dat
new file mode 100644
index 0000000000..485d9401e5
--- /dev/null
+++ b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test5/testinfo.dat
@@ -0,0 +1,13 @@
+#
+# Copyright (c) Microsoft Corporation. All rights reserved.
+#
+
+Version = 1.0
+Section = Locale Information
+Function = WideCharToMultiByte
+Name = Test #5 for WideCharToMultiByte
+TYPE = DEFAULT
+EXE1 = test5
+Description
+=Tests WideCharToMultiByte conversion to UTF-8
+=containing various corner cases \ No newline at end of file
diff --git a/src/pal/tests/palsuite/paltestlist.txt b/src/pal/tests/palsuite/paltestlist.txt
index 44386ac30e..94ac16ab5f 100644
--- a/src/pal/tests/palsuite/paltestlist.txt
+++ b/src/pal/tests/palsuite/paltestlist.txt
@@ -628,6 +628,11 @@ locale_info/IsValidCodePage/test1/paltest_isvalidcodepage_test1
locale_info/MultiByteToWideChar/test1/paltest_multibytetowidechar_test1
locale_info/MultiByteToWideChar/test2/paltest_multibytetowidechar_test2
locale_info/MultiByteToWideChar/test3/paltest_multibytetowidechar_test3
+locale_info/MultiByteToWideChar/test4/paltest_multibytetowidechar_test4
+locale_info/WideCharToMultiByte/test1/paltest_widechartomultibyte_test1
+locale_info/WideCharToMultiByte/test2/paltest_widechartomultibyte_test2
+locale_info/WideCharToMultiByte/test3/paltest_widechartomultibyte_test3
+locale_info/WideCharToMultiByte/test5/paltest_widechartomultibyte_test5
miscellaneous/CharNextA/test1/paltest_charnexta_test1
miscellaneous/CharNextA/test2/paltest_charnexta_test2
miscellaneous/CharNextExA/test1/paltest_charnextexa_test1
diff --git a/src/pal/tests/palsuite/paltestlist_to_be_reviewed.txt b/src/pal/tests/palsuite/paltestlist_to_be_reviewed.txt
index e7ccda5e7f..ac0a2ee4eb 100644
--- a/src/pal/tests/palsuite/paltestlist_to_be_reviewed.txt
+++ b/src/pal/tests/palsuite/paltestlist_to_be_reviewed.txt
@@ -134,9 +134,6 @@ locale_info/GetUserDefaultLCID/test1/paltest_getuserdefaultlcid_test1
locale_info/IsValidCodePage/test2/paltest_isvalidcodepage_test2
locale_info/IsValidLocale/test1/paltest_isvalidlocale_test1
locale_info/SetThreadLocale/test1/paltest_setthreadlocale_test1
-locale_info/WideCharToMultiByte/test1/paltest_widechartomultibyte_test1
-locale_info/WideCharToMultiByte/test2/paltest_widechartomultibyte_test2
-locale_info/WideCharToMultiByte/test3/paltest_widechartomultibyte_test3
locale_info/WideCharToMultiByte/test4/paltest_widechartomultibyte_test4
miscellaneous/FormatMessageW/test4/paltest_formatmessagew_test4
miscellaneous/FormatMessageW/test5/paltest_formatmessagew_test5