summaryrefslogtreecommitdiff
path: root/src/pal/tests/palsuite/locale_info/WideCharToMultiByte
diff options
context:
space:
mode:
Diffstat (limited to 'src/pal/tests/palsuite/locale_info/WideCharToMultiByte')
-rw-r--r--src/pal/tests/palsuite/locale_info/WideCharToMultiByte/CMakeLists.txt7
-rw-r--r--src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test1/test1.c102
-rw-r--r--src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test1/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test2/test2.c88
-rw-r--r--src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test2/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test3/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test3/test3.c100
-rw-r--r--src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test3/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test4/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test4/test4.c131
-rw-r--r--src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test4/testinfo.dat12
-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
16 files changed, 743 insertions, 0 deletions
diff --git a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/CMakeLists.txt
new file mode 100644
index 0000000000..dc5d5131ec
--- /dev/null
+++ b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+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/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test1/CMakeLists.txt
new file mode 100644
index 0000000000..0d1d12b41e
--- /dev/null
+++ b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test1.c
+)
+
+add_executable(paltest_widechartomultibyte_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_widechartomultibyte_test1 coreclrpal)
+
+target_link_libraries(paltest_widechartomultibyte_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test1/test1.c b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test1/test1.c
new file mode 100644
index 0000000000..cd763f33be
--- /dev/null
+++ b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test1/test1.c
@@ -0,0 +1,102 @@
+// 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: test1.c
+**
+** Purpose: Tests WideCharToMultiByte with all the ASCII characters (0-127).
+** Also tests that WideCharToMultiByte handles different buffer
+** lengths correctly (0, -1, and a valid length)
+**
+**
+**==========================================================================*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+ char mbStr[128];
+ WCHAR wideStr[128];
+ int ret;
+ int i;
+ int k;
+ BOOL bRet=TRUE;
+
+ /* These codepages are currently supported by the PAL */
+ int codePages[] ={
+ CP_ACP,
+ CP_UTF8
+ };
+
+
+ if (PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+
+ /* Go through all of the code pages */
+ for(i=0; i<(sizeof(codePages)/sizeof(int)); i++)
+ {
+
+ for (k=0; k<128; k++)
+ {
+ wideStr[k] = 127 - k;
+ mbStr[k] = 0;
+ }
+
+ /* Convert with buffer size of 0 */
+ ret = WideCharToMultiByte(codePages[i], 0, wideStr, -1,
+ mbStr, 0, NULL, NULL);
+ if (ret != 128)
+ {
+ Trace("WideCharToMultiByte did not return correct string length!\n"
+ "Got %d, expected %d for code page %d with error %u.\n",
+ ret, 128,codePages[i],GetLastError());
+ bRet=FALSE;
+ }
+
+ /* Make sure the ASCII set (0-127) gets translated correctly */
+ ret = WideCharToMultiByte(codePages[i], 0, wideStr, -1,
+ mbStr, 128, NULL, NULL);
+ if (ret != 128)
+ {
+ Trace("WideCharToMultiByte did not return correct string length!\n"
+ "Got %d, expected %d for code page %d with error %u.\n",
+ ret, 128,codePages[i],GetLastError());
+ bRet=FALSE;
+ }
+
+ for (k=0; k<128; k++)
+ {
+ if (mbStr[k] != 127 - k)
+ {
+ Trace("WideCharToMultiByte failed to translate correctly!\n"
+ "Expected character %d to be %c (%x), got %c (%x) for "
+ "code page %d\n",k, 127 - k, 127 - k,mbStr[k], mbStr[k],
+ codePages[i]);
+ bRet=FALSE;
+ }
+ }
+
+
+ /* try a 0 length string ("") */
+ wideStr[0] = '\0';
+ ret = WideCharToMultiByte(codePages[i], 0, wideStr, -1,
+ mbStr, 0, NULL, NULL);
+ if (ret != 1)
+ {
+ Trace("WideCharToMultiByte did not return correct string length!\n"
+ "Got %d, expected %d for code page %d with error %u.\n",
+ ret, 1,codePages[i],GetLastError());
+ bRet=FALSE;
+ }
+ }
+
+ int result = bRet ? PASS : FAIL;
+ PAL_TerminateEx(result);
+ return result;
+}
+
diff --git a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test1/testinfo.dat b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test1/testinfo.dat
new file mode 100644
index 0000000000..9fb5f0f032
--- /dev/null
+++ b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test1/testinfo.dat
@@ -0,0 +1,14 @@
+# 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.
+
+Version = 1.0
+Section = Locale Information
+Function = WideCharToMultiByte
+Name = Test #1 for WideCharToMultiByte
+TYPE = DEFAULT
+EXE1 = test1
+Description
+=Tests WideCharToMultiByte with all the ASCII characters (0-127).
+=Also tests that WideCharToMultiByte handles different buffer
+=lengths correctly (0, -1, and a valid length)
diff --git a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test2/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test2/CMakeLists.txt
new file mode 100644
index 0000000000..bbfad2ca9f
--- /dev/null
+++ b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test2/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test2.c
+)
+
+add_executable(paltest_widechartomultibyte_test2
+ ${SOURCES}
+)
+
+add_dependencies(paltest_widechartomultibyte_test2 coreclrpal)
+
+target_link_libraries(paltest_widechartomultibyte_test2
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test2/test2.c b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test2/test2.c
new file mode 100644
index 0000000000..f5d40ae903
--- /dev/null
+++ b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test2/test2.c
@@ -0,0 +1,88 @@
+// 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: test2.c
+**
+** Purpose: Tests that WideCharToMultiByte respects the length of the wide
+** character string.
+**
+**
+**==========================================================================*/
+
+#include <palsuite.h>
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ char mbStr[128];
+ WCHAR wideStr[128];
+ int ret;
+ int i;
+ int k;
+ BOOL bRet=TRUE;
+
+ /* These codepages are currently supported by the PAL */
+ int codePages[] ={
+ CP_ACP,
+ CP_UTF8
+ };
+
+ if (PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+ /* Go through all of the code pages */
+ for(i=0; i<(sizeof(codePages)/sizeof(int)); i++)
+ {
+
+ /* Filling the arrays */
+ for (k=0; k<128; k++)
+ {
+ wideStr[k] = 'a';
+ mbStr[i] = 0;
+ }
+
+ wideStr[127] = 0;
+
+ /* Passing a buffer that is too small */
+ ret = WideCharToMultiByte(codePages[i], 0, wideStr, 10,
+ mbStr, 0, NULL, NULL);
+ if (ret != 10)
+ {
+ Trace("WideCharToMultiByte did not return correct string length!\n"
+ "Got %d, expected %d for %d with error %u.\n", ret, 10,
+ codePages[i], GetLastError());
+ bRet = FALSE;
+ }
+
+ /* Passing a sufficiently large buffer */
+ mbStr[10] = 'b';
+ ret = WideCharToMultiByte(codePages[i], 0, wideStr, 10,
+ mbStr, 128, NULL, NULL);
+ if (ret != 10)
+ {
+ Trace("WideCharToMultiByte did not return correct string length!\n"
+ "Got %d, expected %d for code page %d with error %u.\n",
+ ret, 10, codePages[i], GetLastError());
+ bRet = FALSE;
+ }
+
+ /* Verifying overflow of the destination string did not occur */
+ if (mbStr[10] != 'b')
+ {
+ Trace("WideCharToMultiByte overflowed the destination buffer for "
+ "code page %d.\n", codePages[i]);
+ bRet = FALSE;
+ }
+
+ }
+
+ int result = bRet ? PASS : FAIL;
+ PAL_TerminateEx(result);
+ return result;
+}
+
diff --git a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test2/testinfo.dat b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test2/testinfo.dat
new file mode 100644
index 0000000000..e5b50b8143
--- /dev/null
+++ b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test2/testinfo.dat
@@ -0,0 +1,13 @@
+# 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.
+
+Version = 1.0
+Section = Locale Information
+Function = WideCharToMultiByte
+Name = Test #2 for WideCharToMultiByte
+TYPE = DEFAULT
+EXE1 = test2
+Description
+=Tests that WideCharToMultiByte respects the length of the wide
+=character string.
diff --git a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test3/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test3/CMakeLists.txt
new file mode 100644
index 0000000000..0edfd73931
--- /dev/null
+++ b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test3/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test3.c
+)
+
+add_executable(paltest_widechartomultibyte_test3
+ ${SOURCES}
+)
+
+add_dependencies(paltest_widechartomultibyte_test3 coreclrpal)
+
+target_link_libraries(paltest_widechartomultibyte_test3
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test3/test3.c b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test3/test3.c
new file mode 100644
index 0000000000..ecd26addb4
--- /dev/null
+++ b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test3/test3.c
@@ -0,0 +1,100 @@
+// 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: test3.c
+**
+** Purpose: Tests that WideCharToMultiByte correctly handles the following
+** error conditions: insufficient buffer space, invalid code pages,
+** and invalid flags.
+**
+**
+**==========================================================================*/
+
+
+#include <palsuite.h>
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ char mbStr[128];
+ WCHAR wideStr[128];
+ int ret;
+ int i;
+ int k;
+ BOOL bRet=TRUE;
+
+ /* These codepages are currently supported by the PAL */
+ int codePages[] ={
+ CP_ACP,
+ CP_UTF8
+ };
+
+
+ if (PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+ /* Go through all of the code pages */
+ for(i=0; i<(sizeof(codePages)/sizeof(int)); i++)
+ {
+
+ for (k=0; k<128; k++)
+ {
+ wideStr[k] = 'a';
+ mbStr[k] = 0;
+ }
+
+ wideStr[127] = 0;
+
+ /* try with insufficient buffer space */
+ ret = WideCharToMultiByte(codePages[i], 0, wideStr, -1,
+ mbStr, 10, NULL, NULL);
+ if (ret != 0)
+ {
+ Trace("WideCharToMultiByte did not return an error!\n"
+ "Expected return of 0, got %d for code page %d.\n", ret,
+ codePages[i]);
+ bRet = FALSE;
+ }
+
+ ret = GetLastError();
+ if (ret != ERROR_INSUFFICIENT_BUFFER)
+ {
+ Fail("WideCharToMultiByte set the last error to %u instead of "
+ "ERROR_INSUFFICIENT_BUFFER for code page %d.\n",
+ GetLastError(),codePages[i]);
+ bRet = FALSE;
+ }
+ }
+
+ /* Return failure if any of the code pages returned the wrong results */
+ if(!bRet)
+ {
+ return FAIL;
+ }
+
+ /* try with a wacky code page */
+ ret = WideCharToMultiByte(-1, 0, wideStr, -1, mbStr, 128, NULL, NULL);
+ if (ret != 0)
+ {
+ Fail("WideCharToMultiByte did not return an error!\n"
+ "Expected return of 0, got %d for invalid code page.\n", ret);
+ }
+
+ ret = GetLastError();
+ if (ret != ERROR_INVALID_PARAMETER)
+ {
+ Fail("WideCharToMultiByte set the last error to %u instead of "
+ "ERROR_INVALID_PARAMETER for invalid code page -1.\n",
+ GetLastError());
+ }
+
+ PAL_Terminate();
+
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test3/testinfo.dat b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test3/testinfo.dat
new file mode 100644
index 0000000000..b737686c39
--- /dev/null
+++ b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test3/testinfo.dat
@@ -0,0 +1,14 @@
+# 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.
+
+Version = 1.0
+Section = Locale Information
+Function = WideCharToMultiByte
+Name = Test #3 for WideCharToMultiByte
+TYPE = DEFAULT
+EXE1 = test3
+Description
+=Tests that WideCharToMultiByte correctly handles the following
+=error conditions: insufficient buffer space and invalid code pages.
+
diff --git a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test4/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test4/CMakeLists.txt
new file mode 100644
index 0000000000..f0ffd84ee9
--- /dev/null
+++ b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/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_widechartomultibyte_test4
+ ${SOURCES}
+)
+
+add_dependencies(paltest_widechartomultibyte_test4 coreclrpal)
+
+target_link_libraries(paltest_widechartomultibyte_test4
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test4/test4.c b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test4/test4.c
new file mode 100644
index 0000000000..8ab5fe90af
--- /dev/null
+++ b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test4/test4.c
@@ -0,0 +1,131 @@
+// 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 that WideCharToMultiByte correctly handles WC_NO_BEST_FIT_CHARS
+**
+**
+**==========================================================================*/
+
+
+#include <palsuite.h>
+
+/* C with a circumflex */
+wchar_t ustr[2] = { 0x108, 0 };
+
+/* expected conversion when best fit is allowed on Windows */
+char* lpBestFitRes = "C";
+
+/* expected conversion when no default character is specified */
+char* lpResStr1 = "?";
+
+/* expected conversion when the default character is 'k' */
+char myDefaultChar = 'k';
+char* lpResStr2 = "k";
+
+int
+TestWideCharToMultiByte(
+ IN UINT CodePage,
+ IN DWORD dwFlags,
+ IN LPCSTR lpDefaultChar,
+ IN LPSTR lpResStr)
+{
+ char mbstr[30];
+ int ret;
+ int testStatus = PASS;
+ BOOL usedDefaultChar = FALSE;
+
+ printf("WideCharToMultiByte (CodePage=%d, dwFlags=%#x, default=%c)\n",
+ CodePage, dwFlags, lpDefaultChar?*lpDefaultChar:' ');
+ ret = WideCharToMultiByte(CodePage, dwFlags, ustr, -1, mbstr, sizeof(mbstr),
+ lpDefaultChar, &usedDefaultChar);
+ if (ret != 0) {
+ printf(" converted C with circumflex to in Unicode to multibyte: "
+ "\"%s\"\n", mbstr);
+ printf(" used default character?: %d\n", usedDefaultChar);
+ if (strcmp(mbstr, lpResStr) != 0 || usedDefaultChar != TRUE)
+ {
+ printf("!!!! failed conversion !!!!\n");
+ testStatus = FAIL;
+ }
+ }
+ else {
+ printf("!!!! failed conversion !!!!\n");
+ testStatus = FAIL;
+ }
+ return testStatus;
+}
+
+int __cdecl main(int argc, char *argv[])
+{
+ int testStatus = PASS;
+
+ if (PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+ /* Use WideCharToMultiByte to convert the string in code page CP_ACP.
+ * Note that the resulting string will be different on Windows PAL and
+ * Unix PAL. On Windows, the default best fit behavior will map C with
+ * circumflex to C.
+ *
+ * testStatus |= TestWideCharToMultiByte(CP_ACP, 0, NULL, lpBestFitRes);
+ *
+ * On Unix, where there is no support for finding best fit, it will be
+ * mapped to a '?'. In addition, it will trigger an ASSERT in the dbg/chk
+ * builds.
+ *
+ * testStatus |= TestWideCharToMultiByte(CP_ACP, 0, NULL, lpResStr1);
+ */
+
+ /* Use WideCharToMultiByte with WC_NO_BEST_FIR_CHARS to convert the string
+ * in CP_ACP (1252 by default). This will prevent it from mapping the C
+ * with circumflex to its closest match in the ANSI code page: C
+ */
+ testStatus |= TestWideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, NULL, lpResStr1);
+
+
+ /* Use WideCharToMultiByte with WC_NO_BEST_FIR_CHARS and a default character
+ * to convert the string. This will prevent it from mapping the C with
+ * circumflex to its closest match in the ANSI code page: C. It will be
+ * replaced with the specified default character.
+ */
+ testStatus |= TestWideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, &myDefaultChar, lpResStr2);
+
+ /* Use WideCharToMultiByte to convert the string in code page 1253
+ * Note that the resulting string will be different on Windows PAL and
+ * Unix PAL. On Windows, the default best fit behavior will map C with
+ * circumflex to C.
+ *
+ * testStatus |= TestWideCharToMultiByte(1253, 0, NULL, lpBestFitRes);
+ *
+ * On Unix, where there is no support for finding best fit, it will be
+ * mapped to a '?'. In addition, it will trigger an ASSERT in the dbg/chk
+ * builds.
+ *
+ * testStatus |= TestWideCharToMultiByte(1253, 0, NULL, lpResStr1);
+ */
+
+ /* Use WideCharToMultiByte with WC_NO_BEST_FIR_CHARS to convert the string
+ * in 1253. This will prevent it from mapping the C
+ * with circumflex to its closest match in the ANSI code page: C
+ */
+ testStatus |= TestWideCharToMultiByte(1253, WC_NO_BEST_FIT_CHARS, NULL, lpResStr1);
+
+ /* Use WideCharToMultiByte with WC_NO_BEST_FIR_CHARS and a default
+ * character to convert the string in 1253. This will prevent it from
+ * mapping the C with circumflex to its closest match in the ANSI code
+ * page: C. It will be replaced with the specified default character.
+ */
+ testStatus |= TestWideCharToMultiByte(1253, WC_NO_BEST_FIT_CHARS, &myDefaultChar, lpResStr2);
+
+ PAL_TerminateEx(testStatus);
+
+ return testStatus;
+}
+
diff --git a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test4/testinfo.dat b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test4/testinfo.dat
new file mode 100644
index 0000000000..03b00d3548
--- /dev/null
+++ b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test4/testinfo.dat
@@ -0,0 +1,12 @@
+# 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.
+
+Version = 1.0
+Section = Locale Information
+Function = WideCharToMultiByte
+Name = Test #4 for WideCharToMultiByte
+TYPE = DEFAULT
+EXE1 = test4
+Description
+=Tests that WideCharToMultiByte correctly handles WC_NO_BEST_FIT_CHARS
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