https://git.reactos.org/?p=reactos.git;a=commitdiff;h=3400a27ca50d321302c639a473e4ce775b5dc8d5

commit 3400a27ca50d321302c639a473e4ce775b5dc8d5
Author:     Katayama Hirofumi MZ <[email protected]>
AuthorDate: Fri Apr 5 22:04:04 2019 +0900
Commit:     GitHub <[email protected]>
CommitDate: Fri Apr 5 22:04:04 2019 +0900

    [KERNEL32_APITEST] Improve MultiByteToWideChar testcase (#1472)
    
    Strengthen the testcase for kernel32!MultiByteToWideChar function. 
ROSTESTS-282
---
 .../apitests/kernel32/MultiByteToWideChar.c        | 176 ++++++++++++++++++++-
 1 file changed, 169 insertions(+), 7 deletions(-)

diff --git a/modules/rostests/apitests/kernel32/MultiByteToWideChar.c 
b/modules/rostests/apitests/kernel32/MultiByteToWideChar.c
index 120ce60f90..5b59acbe98 100644
--- a/modules/rostests/apitests/kernel32/MultiByteToWideChar.c
+++ b/modules/rostests/apitests/kernel32/MultiByteToWideChar.c
@@ -2,18 +2,180 @@
  * PROJECT:         ReactOS api tests
  * LICENSE:         GPLv2+ - See COPYING in the top level directory
  * PURPOSE:         Test for MultiByteToWideChar
- * PROGRAMMER:      Mike "tamlin" Nordell
+ * PROGRAMMERS:     Mike "tamlin" Nordell
+ *                  Katayama Hirofumi MZ <[email protected]>
  */
 
 #include "precomp.h"
 
-START_TEST(MultiByteToWideChar)
+/* NOTE: Tested on Win10. We follow Win10 in this function.
+         Win10 might alter its design in future. */
+
+/* TODO: Russian, French, Korean etc. codepages */
+
+#define CP932   932     /* Japanese Shift_JIS (SJIS) codepage */
+
+/* "Japanese" in Japanese UTF-8 */
+static const char UTF8_Japanese[] = "\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E";
+/* "Japanese" in Japanese Shift_JIS */
+static const char SJIS_Japanese[] = "\x93\xFA\x96\x7B\x8C\xEA";
+
+#define MAX_BUFFER  8
+
+/* test entry */
+typedef struct ENTRY
+{
+    int LineNo;
+    int Return;
+    DWORD Error;
+    UINT CodePage;
+    DWORD Flags;
+    const char *Src;
+    int SrcLen;
+    int DestLen;
+    WCHAR CheckDest[MAX_BUFFER];
+    int CheckLen;
+    BOOL SamePointer;
+} ENTRY;
+
+static const ENTRY Entries[] =
+{
+    /* without buffer */
+    { __LINE__, 1, 0xBEAF, CP_UTF8, 0, "a", 1 },
+    { __LINE__, 2, 0xBEAF, CP_UTF8, 0, "a", 2 },
+    { __LINE__, 2, 0xBEAF, CP_UTF8, MB_ERR_INVALID_CHARS, "a", 2 },
+    /* negative length */
+    { __LINE__, 2, 0xBEAF, CP_UTF8, 0, "a", -1 },
+    { __LINE__, 2, 0xBEAF, CP_UTF8, 0, "a", -2 },
+    { __LINE__, 2, 0xBEAF, CP_UTF8, MB_ERR_INVALID_CHARS, "a", -1 },
+    { __LINE__, 2, 0xBEAF, CP_UTF8, MB_ERR_INVALID_CHARS, "a", -3 },
+    /* with buffer */
+    { __LINE__, 1, 0xBEAF, CP_UTF8, 0, "a", 1, 1, {'a', 0x7F7F}, 2 },
+    { __LINE__, 2, 0xBEAF, CP_UTF8, 0, "a", 2, 4, {'a', 0, 0x7F7F}, 3 },
+    { __LINE__, 2, 0xBEAF, CP_UTF8, MB_ERR_INVALID_CHARS, "a", 2, 4, {'a', 0, 
0x7F7F}, 3 },
+    /* short buffer */
+    { __LINE__, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, 0, "a", 2, 1, {'a', 
0x7F7F}, 2 },
+    { __LINE__, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, 0, "a", 2, 1, {'a', 
0x7F7F}, 2 },
+    { __LINE__, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, MB_ERR_INVALID_CHARS, 
"a", 2, 1, {'a', 0x7F7F}, 2 },
+    /* same pointer */
+    { __LINE__, 0, ERROR_INVALID_PARAMETER, CP_UTF8, 0, "", 1, 1, { 0x7F7F }, 
1, TRUE },
+    { __LINE__, 0, ERROR_INVALID_PARAMETER, CP_UTF8, MB_ERR_INVALID_CHARS, "", 
1, 1, { 0x7F7F }, 1, TRUE },
+    /* invalid UTF-8 sequences without buffer */
+    { __LINE__, 2, 0xBEAF, CP_UTF8, 0, "\xC0", 2 },
+    { __LINE__, 4, 0xBEAF, CP_UTF8, 0, "\xC0\xC0\x80", 4 },
+    { __LINE__, 3, 0xBEAF, CP_UTF8, 0, "\xE0\xC0", 3 },
+    { __LINE__, 4, 0xBEAF, CP_UTF8, 0, "\xE0\x20\xC0", 4 },
+    { __LINE__, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, 
MB_ERR_INVALID_CHARS, "\xC0", 2 },
+    { __LINE__, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, 
MB_ERR_INVALID_CHARS, "\xC0\xC0\x80", 4 },
+    { __LINE__, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, 
MB_ERR_INVALID_CHARS, "\xE0\xC0", 3 },
+    { __LINE__, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, 
MB_ERR_INVALID_CHARS, "\xE0\x20\xC0", 4 },
+    /* invalid UTF-8 sequences with buffer */
+    { __LINE__, 2, 0xBEAF, CP_UTF8, 0, "\xC0", 2, 4, {0xFFFD, 0, 0x7F7F}, 3},
+    { __LINE__, 4, 0xBEAF, CP_UTF8, 0, "\xC0\xC0\x80", 4, 5, {0xFFFD, 0xFFFD, 
0xFFFD, 0, 0x7F7F}, 5 },
+    { __LINE__, 3, 0xBEAF, CP_UTF8, 0, "\xE0\xC0", 3, 4, {0xFFFD, 0xFFFD, 0, 
0x7F7F}, 4 },
+    { __LINE__, 4, 0xBEAF, CP_UTF8, 0, "\xE0\x20\xC0", 4, 5, {0xFFFD, 0x0020, 
0xFFFD, 0, 0x7F7F}, 5 },
+    { __LINE__, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, 
MB_ERR_INVALID_CHARS, "\xC0", 2, 4, {0xFFFD, 0, 0x7F7F}, 3 },
+    { __LINE__, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, 
MB_ERR_INVALID_CHARS, "\xC0\xC0\x80", 4, 5, {0xFFFD, 0xFFFD, 0xFFFD, 0, 
0x7F7F}, 5 },
+    { __LINE__, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, 
MB_ERR_INVALID_CHARS, "\xE0\xC0", 3, 4, {0xFFFD, 0xFFFD, 0, 0x7F7F}, 4 },
+    { __LINE__, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, 
MB_ERR_INVALID_CHARS, "\xE0\x20\xC0", 4, 5, {0xFFFD, 0x0020, 0xFFFD, 0, 
0x7F7F}, 5 },
+    /* invalid UTF-8 sequences with short buffer */
+    { __LINE__, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, 0, "\xC0", 2, 1, 
{0xFFFD, 0x7F7F}, 2},
+    { __LINE__, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, 0, "\xC0\xC0\x80", 4, 
1, {0xFFFD, 0x7F7F}, 2 },
+    { __LINE__, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, 0, "\xE0\xC0", 3, 1, 
{0xFFFD, 0x7F7F}, 2 },
+    { __LINE__, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, 0, "\xE0\x20\xC0", 4, 
1, {0xFFFD, 0x7F7F}, 2 },
+    { __LINE__, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, MB_ERR_INVALID_CHARS, 
"\xC0", 2, 1, {0xFFFD, 0x7F7F}, 2 },
+    { __LINE__, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, MB_ERR_INVALID_CHARS, 
"\xC0\xC0\x80", 4, 1, {0xFFFD, 0x7F7F}, 2 },
+    { __LINE__, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, MB_ERR_INVALID_CHARS, 
"\xE0\xC0", 3, 1, {0xFFFD, 0x7F7F}, 2 },
+    { __LINE__, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, MB_ERR_INVALID_CHARS, 
"\xE0\x20\xC0", 4, 1, {0xFFFD, 0x7F7F}, 2 },
+    /* Japanese UTF-8 without buffer */
+    { __LINE__, 4, 0xBEAF, CP_UTF8, 0, UTF8_Japanese, sizeof(UTF8_Japanese) },
+    { __LINE__, 4, 0xBEAF, CP_UTF8, MB_ERR_INVALID_CHARS, UTF8_Japanese, 
sizeof(UTF8_Japanese) },
+    /* Japanese UTF-8 with buffer */
+    { __LINE__, 4, 0xBEAF, CP_UTF8, 0, UTF8_Japanese, sizeof(UTF8_Japanese), 
4, {0x65E5, 0x672C, 0x8A9E, 0, 0x7F7F}, 5 },
+    { __LINE__, 4, 0xBEAF, CP_UTF8, MB_ERR_INVALID_CHARS, UTF8_Japanese, 
sizeof(UTF8_Japanese), 4, {0x65E5, 0x672C, 0x8A9E, 0, 0x7F7F}, 5 },
+    /* Japanese UTF-8 with short buffer */
+    { __LINE__, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, 0, UTF8_Japanese, 
sizeof(UTF8_Japanese), 1, {0x65E5, 0x7F7F}, 2 },
+    { __LINE__, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, MB_ERR_INVALID_CHARS, 
UTF8_Japanese, sizeof(UTF8_Japanese), 1, {0x65E5, 0x7F7F}, 2 },
+    /* Japanese UTF-8 truncated source */
+    { __LINE__, 1, 0xBEAF, CP_UTF8, 0, UTF8_Japanese, 1, 4, {0xFFFD, 0x7F7F}, 
2 },
+    { __LINE__, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, 
MB_ERR_INVALID_CHARS, UTF8_Japanese, 1, 4, {0xFFFD, 0x7F7F}, 2 },
+    /* Japanese CP932 without buffer */
+    { __LINE__, 4, 0xBEAF, CP932, 0, SJIS_Japanese, sizeof(SJIS_Japanese) },
+    { __LINE__, 4, 0xBEAF, CP932, MB_ERR_INVALID_CHARS, SJIS_Japanese, 
sizeof(SJIS_Japanese) },
+    /* Japanese CP932 with buffer */
+    { __LINE__, 4, 0xBEAF, CP932, 0, SJIS_Japanese, sizeof(SJIS_Japanese), 4, 
{0x65E5, 0x672C, 0x8A9E, 0, 0x7F7F}, 5 },
+    { __LINE__, 4, 0xBEAF, CP932, MB_ERR_INVALID_CHARS, SJIS_Japanese, 
sizeof(SJIS_Japanese), 4, {0x65E5, 0x672C, 0x8A9E, 0, 0x7F7F}, 5 },
+    /* Japanese CP932 with short buffer */
+    { __LINE__, 0, ERROR_INSUFFICIENT_BUFFER, CP932, 0, SJIS_Japanese, 
sizeof(SJIS_Japanese), 1, {0x65E5, 0x7F7F}, 2 },
+    { __LINE__, 0, ERROR_INSUFFICIENT_BUFFER, CP932, MB_ERR_INVALID_CHARS, 
SJIS_Japanese, sizeof(SJIS_Japanese), 1, {0x65E5, 0x7F7F}, 2 },
+    /* Japanese CP932 truncated source */
+    { __LINE__, 1, 0xBEAF, CP932, 0, SJIS_Japanese, 1, 4, {0x30FB, 0x7F7F}, 2 
},
+    { __LINE__, 0, ERROR_NO_UNICODE_TRANSLATION, CP932, MB_ERR_INVALID_CHARS, 
SJIS_Japanese, 1, 4, {0x7F7F, 0x7F7F}, 2 },
+};
+
+static void TestEntry(const ENTRY *pEntry)
 {
-    int ret;
+    int ret, i;
+    WCHAR Buffer[MAX_BUFFER];
+    DWORD Error;
 
-    ret = MultiByteToWideChar(CP_UTF8, 0, "a", sizeof("a"), 0, 0);
-    ok(ret == 2, "ret should be 2, is %d\n", ret);
+    FillMemory(Buffer, sizeof(Buffer), 0x7F);
+    SetLastError(0xBEAF);
 
-    ret = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, "a", sizeof("a"), 
0, 0);
-    ok(ret == 2, "ret should be 2, is %d\n", ret);
+    if (pEntry->DestLen == 0)
+    {
+        /* dest is NULL */
+        ret = MultiByteToWideChar(pEntry->CodePage, pEntry->Flags, pEntry->Src,
+                                  pEntry->SrcLen, NULL, 0);
+    }
+    else
+    {
+        ok(pEntry->DestLen >= pEntry->CheckLen - 1,
+           "Line %d: DestLen was shorter than (CheckLen - 1)\n", 
pEntry->LineNo);
+
+        if (pEntry->SamePointer)
+        {
+            /* src ptr == dest ptr */
+            ret = MultiByteToWideChar(pEntry->CodePage, pEntry->Flags,
+                                      (const char *)Buffer, pEntry->SrcLen,
+                                      Buffer, pEntry->DestLen);
+        }
+        else
+        {
+            /* src ptr != dest ptr */
+            ret = MultiByteToWideChar(pEntry->CodePage, pEntry->Flags,
+                                      pEntry->Src, pEntry->SrcLen,
+                                      Buffer, pEntry->DestLen);
+        }
+    }
+
+    Error = GetLastError();
+
+    /* check ret */
+    ok(ret == pEntry->Return, "Line %d: ret expected %d, got %d\n",
+       pEntry->LineNo, pEntry->Return, ret);
+
+    /* check error code */
+    ok(Error == pEntry->Error,
+       "Line %d: Wrong last error. Expected %lu, got %lu\n",
+       pEntry->LineNo, pEntry->Error, Error);
+
+    if (pEntry->DestLen)
+    {
+        /* check buffer */
+        for (i = 0; i < pEntry->CheckLen; ++i)
+        {
+            ok(Buffer[i] == pEntry->CheckDest[i], "Line %d: Buffer[%d] 
expected %d, got %d\n",
+               pEntry->LineNo, i, pEntry->CheckDest[i], Buffer[i]);
+        }
+    }
+}
+
+START_TEST(MultiByteToWideChar)
+{
+    size_t i;
+    for (i = 0; i < _countof(Entries); ++i)
+    {
+        TestEntry(&Entries[i]);
+    }
 }

Reply via email to