1 /* 2 * PROJECT: ReactOS api tests 3 * LICENSE: GPLv2+ - See COPYING in the top level directory 4 * PURPOSE: Test for MultiByteToWideChar 5 * PROGRAMMERS: Mike "tamlin" Nordell 6 * Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com> 7 */ 8 9 #include "precomp.h" 10 #include <versionhelpers.h> 11 12 static ULONG OsVersion; 13 14 /* TODO: Russian, French, Korean etc. codepages */ 15 16 #define CP932 932 /* Japanese Shift_JIS (SJIS) codepage */ 17 18 /* "Japanese" in Japanese UTF-8 */ 19 static const char UTF8_Japanese[] = "\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E"; 20 /* "Japanese" in Japanese Shift_JIS */ 21 static const char SJIS_Japanese[] = "\x93\xFA\x96\x7B\x8C\xEA"; 22 23 #define MAX_BUFFER 10 24 25 /* test entry */ 26 typedef struct ENTRY 27 { 28 int LineNo; 29 ULONG VersionRange[2]; 30 int Return; 31 DWORD Error; 32 UINT CodePage; 33 DWORD Flags; 34 const char *Src; 35 int SrcLen; 36 int DestLen; 37 WCHAR CheckDest[MAX_BUFFER]; 38 int CheckLen; 39 BOOL SamePointer; 40 } ENTRY; 41 42 static const ENTRY Entries[] = 43 { 44 /* without buffer */ 45 { __LINE__, {0x000,0xA00}, 1, 0xBEAF, CP_UTF8, 0, "a", 1 }, 46 { __LINE__, {0x000,0xA00}, 2, 0xBEAF, CP_UTF8, 0, "a", 2 }, 47 { __LINE__, {0x000,0xA00}, 2, 0xBEAF, CP_UTF8, MB_ERR_INVALID_CHARS, "a", 2 }, 48 /* negative length */ 49 { __LINE__, {0x000,0xA00}, 2, 0xBEAF, CP_UTF8, 0, "a", -1 }, 50 { __LINE__, {0x000,0xA00}, 2, 0xBEAF, CP_UTF8, 0, "a", -2 }, 51 { __LINE__, {0x000,0xA00}, 2, 0xBEAF, CP_UTF8, MB_ERR_INVALID_CHARS, "a", -1 }, 52 { __LINE__, {0x000,0xA00}, 2, 0xBEAF, CP_UTF8, MB_ERR_INVALID_CHARS, "a", -3 }, 53 /* with buffer */ 54 { __LINE__, {0x000,0xA00}, 1, 0xBEAF, CP_UTF8, 0, "a", 1, 1, {'a', 0x7F7F}, 2 }, 55 { __LINE__, {0x000,0xA00}, 2, 0xBEAF, CP_UTF8, 0, "a", 2, 4, {'a', 0, 0x7F7F}, 3 }, 56 { __LINE__, {0x000,0xA00}, 2, 0xBEAF, CP_UTF8, MB_ERR_INVALID_CHARS, "a", 2, 4, {'a', 0, 0x7F7F}, 3 }, 57 /* short buffer */ 58 { __LINE__, {0x000,0xA00}, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, 0, "a", 2, 1, {'a', 0x7F7F}, 2 }, 59 { __LINE__, {0x000,0xA00}, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, 0, "a", 2, 1, {'a', 0x7F7F}, 2 }, 60 { __LINE__, {0x000,0xA00}, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, MB_ERR_INVALID_CHARS, "a", 2, 1, {'a', 0x7F7F}, 2 }, 61 /* same pointer */ 62 { __LINE__, {0x000,0xA00}, 0, ERROR_INVALID_PARAMETER, CP_UTF8, 0, "", 1, 1, { 0x7F7F }, 1, TRUE }, 63 { __LINE__, {0x000,0xA00}, 0, ERROR_INVALID_PARAMETER, CP_UTF8, MB_ERR_INVALID_CHARS, "", 1, 1, { 0x7F7F }, 1, TRUE }, 64 /* invalid UTF-8 sequences without buffer */ 65 { __LINE__, {0x000,0x502}, 1, 0xBEAF, CP_UTF8, 0, "\xC0", 2 }, 66 { __LINE__, {0x600,0xA00}, 2, 0xBEAF, CP_UTF8, 0, "\xC0", 2 }, 67 { __LINE__, {0x000,0x502}, 1, 0xBEAF, CP_UTF8, 0, "\xC0\xC0\x80", 4 }, 68 { __LINE__, {0x600,0xA00}, 4, 0xBEAF, CP_UTF8, 0, "\xC0\xC0\x80", 4 }, 69 { __LINE__, {0x000,0x502}, 1, 0xBEAF, CP_UTF8, 0, "\xE0\xC0", 3 }, 70 { __LINE__, {0x600,0xA00}, 3, 0xBEAF, CP_UTF8, 0, "\xE0\xC0", 3 }, 71 { __LINE__, {0x000,0x502}, 2, 0xBEAF, CP_UTF8, 0, "\xE0\x20\xC0", 4 }, 72 { __LINE__, {0x600,0xA00}, 4, 0xBEAF, CP_UTF8, 0, "\xE0\x20\xC0", 4 }, 73 { __LINE__, {0x000,0x502}, 1, 0xBEAF, CP_UTF8, 0, "\x82\xA0\x82\xA2", -1 }, 74 { __LINE__, {0x600,0xA00}, 5, 0xBEAF, CP_UTF8, 0, "\x82\xA0\x82\xA2", -1 }, 75 { __LINE__, {0x000,0x502}, 1, 0xBEAF, CP_UTF8, 0, "\x82\xA0\x82\xA2\x82", -1 }, 76 { __LINE__, {0x600,0xA00}, 6, 0xBEAF, CP_UTF8, 0, "\x82\xA0\x82\xA2\x82", -1 }, 77 { __LINE__, {0x000,0xA00}, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, MB_ERR_INVALID_CHARS, "\xC0", 2 }, 78 { __LINE__, {0x000,0xA00}, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, MB_ERR_INVALID_CHARS, "\xC0\xC0\x80", 4 }, 79 { __LINE__, {0x000,0xA00}, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, MB_ERR_INVALID_CHARS, "\xE0\xC0", 3 }, 80 { __LINE__, {0x000,0xA00}, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, MB_ERR_INVALID_CHARS, "\xE0\x20\xC0", 4 }, 81 { __LINE__, {0x000,0xA00}, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, MB_ERR_INVALID_CHARS, "\x82\xA0\x82\xA2", -1 }, 82 { __LINE__, {0x000,0xA00}, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, MB_ERR_INVALID_CHARS, "\x82\xA0\x82\xA2\x82", -1 }, 83 /* invalid UTF-8 sequences with buffer */ 84 { __LINE__, {0x000,0x502}, 1, 0xBEAF, CP_UTF8, 0, "\xC0", 2, 4, {0x00, 0x7F7F, 0x7F7F}, 3}, 85 { __LINE__, {0x600,0xA00}, 2, 0xBEAF, CP_UTF8, 0, "\xC0", 2, 4, {0xFFFD, 0, 0x7F7F}, 3}, 86 { __LINE__, {0x000,0x502}, 1, 0xBEAF, CP_UTF8, 0, "\xC0\xC0\x80", 4, 5, {0x00, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F}, 5 }, 87 { __LINE__, {0x600,0xA00}, 4, 0xBEAF, CP_UTF8, 0, "\xC0\xC0\x80", 4, 5, {0xFFFD, 0xFFFD, 0xFFFD, 0, 0x7F7F}, 5 }, 88 { __LINE__, {0x000,0x502}, 1, 0xBEAF, CP_UTF8, 0, "\xE0\xC0", 3, 4, {0, 0x7F7F, 0x7F7F, 0x7F7F}, 4 }, 89 { __LINE__, {0x600,0xA00}, 3, 0xBEAF, CP_UTF8, 0, "\xE0\xC0", 3, 4, {0xFFFD, 0xFFFD, 0, 0x7F7F}, 4 }, 90 { __LINE__, {0x000,0x502}, 2, 0xBEAF, CP_UTF8, 0, "\xE0\x20\xC0", 4, 5, {0x0020, 0, 0x7F7F, 0x7F7F, 0x7F7F}, 5 }, 91 { __LINE__, {0x600,0xA00}, 4, 0xBEAF, CP_UTF8, 0, "\xE0\x20\xC0", 4, 5, {0xFFFD, 0x0020, 0xFFFD, 0, 0x7F7F}, 5 }, 92 { __LINE__, {0x000,0x502}, 1, 0xBEAF, CP_UTF8, 0, "\x82\xA0\x82\xA2", -1, 5, {0, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F}, 5 }, 93 { __LINE__, {0x600,0xA00}, 5, 0xBEAF, CP_UTF8, 0, "\x82\xA0\x82\xA2", -1, 5, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0}, 5 }, 94 { __LINE__, {0x000,0x502}, 1, 0xBEAF, CP_UTF8, 0, "\x82\xA0\x82\xA2\x82", -1, 8, {0, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F}, 6 }, 95 { __LINE__, {0x600,0xA00}, 6, 0xBEAF, CP_UTF8, 0, "\x82\xA0\x82\xA2\x82", -1, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0}, 6 }, 96 { __LINE__, {0x000,0x502}, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, MB_ERR_INVALID_CHARS, "\xC0", 2, 4, {0x7F7F, 0x7F7F, 0x7F7F}, 3 }, 97 { __LINE__, {0x600,0xA00}, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, MB_ERR_INVALID_CHARS, "\xC0", 2, 4, {0xFFFD, 0, 0x7F7F}, 3 }, 98 { __LINE__, {0x000,0x502}, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, MB_ERR_INVALID_CHARS, "\xC0\xC0\x80", 4, 5, {0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F}, 5 }, 99 { __LINE__, {0x600,0xA00}, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, MB_ERR_INVALID_CHARS, "\xC0\xC0\x80", 4, 5, {0xFFFD, 0xFFFD, 0xFFFD, 0, 0x7F7F}, 5 }, 100 { __LINE__, {0x000,0x502}, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, MB_ERR_INVALID_CHARS, "\xE0\xC0", 3, 4, {0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F}, 4 }, 101 { __LINE__, {0x600,0xA00}, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, MB_ERR_INVALID_CHARS, "\xE0\xC0", 3, 4, {0xFFFD, 0xFFFD, 0, 0x7F7F}, 4 }, 102 { __LINE__, {0x000,0x502}, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, MB_ERR_INVALID_CHARS, "\xE0\x20\xC0", 4, 5, {0x0020, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F}, 5 }, 103 { __LINE__, {0x600,0xA00}, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, MB_ERR_INVALID_CHARS, "\xE0\x20\xC0", 4, 5, {0xFFFD, 0x0020, 0xFFFD, 0, 0x7F7F}, 5 }, 104 { __LINE__, {0x000,0x502}, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, MB_ERR_INVALID_CHARS, "\x82\xA0\x82\xA2", -1, 6, {0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F}, 6 }, 105 { __LINE__, {0x600,0xA00}, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, MB_ERR_INVALID_CHARS, "\x82\xA0\x82\xA2", -1, 6, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0, 0x7F7F}, 6 }, 106 { __LINE__, {0x000,0x502}, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, MB_ERR_INVALID_CHARS, "\x82\xA0\x82\xA2\x82", -1, 7, {0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F}, 7 }, 107 { __LINE__, {0x600,0xA00}, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, MB_ERR_INVALID_CHARS, "\x82\xA0\x82\xA2\x82", -1, 7, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0, 0x7F7F}, 7 }, 108 /* invalid UTF-8 sequences with short buffer */ 109 { __LINE__, {0x000,0x502}, 1, 0xBEAF, CP_UTF8, 0, "\xC0", 2, 1, {0, 0x7F7F}, 2}, 110 { __LINE__, {0x600,0xA00}, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, 0, "\xC0", 2, 1, {0xFFFD, 0x7F7F}, 2}, 111 { __LINE__, {0x000,0x502}, 1, 0xBEAF, CP_UTF8, 0, "\xC0\xC0\x80", 4, 1, {0, 0x7F7F}, 2 }, 112 { __LINE__, {0x600,0xA00}, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, 0, "\xC0\xC0\x80", 4, 1, {0xFFFD, 0x7F7F}, 2 }, 113 { __LINE__, {0x000,0x502}, 1, 0xBEAF, CP_UTF8, 0, "\xE0\xC0", 3, 1, {0, 0x7F7F}, 2 }, 114 { __LINE__, {0x600,0xA00}, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, 0, "\xE0\xC0", 3, 1, {0xFFFD, 0x7F7F}, 2 }, 115 { __LINE__, {0x000,0x502}, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, 0, "\xE0\x20\xC0", 4, 1, {0x0020, 0x7F7F}, 2 }, 116 { __LINE__, {0x600,0xA00}, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, 0, "\xE0\x20\xC0", 4, 1, {0xFFFD, 0x7F7F}, 2 }, 117 { __LINE__, {0x000,0x502}, 1, 0xBEAF, CP_UTF8, 0, "\x82\xA0\x82\xA2", -1, 1, {0, 0x7F7F}, 2 }, 118 { __LINE__, {0x600,0xA00}, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, 0, "\x82\xA0\x82\xA2", -1, 1, {0xFFFD, 0x7F7F}, 2 }, 119 { __LINE__, {0x000,0x502}, 1, 0xBEAF, CP_UTF8, 0, "\x82\xA0\x82\xA2\x82", -1, 1, {0, 0x7F7F}, 2 }, 120 { __LINE__, {0x600,0xA00}, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, 0, "\x82\xA0\x82\xA2\x82", -1, 1, {0xFFFD, 0x7F7F}, 2 }, 121 { __LINE__, {0x000,0x502}, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, MB_ERR_INVALID_CHARS, "\xC0", 2, 1, {0x7F7F, 0x7F7F}, 2 }, 122 { __LINE__, {0x600,0xA00}, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, MB_ERR_INVALID_CHARS, "\xC0", 2, 1, {0xFFFD, 0x7F7F}, 2 }, 123 { __LINE__, {0x000,0x502}, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, MB_ERR_INVALID_CHARS, "\xC0\xC0\x80", 4, 1, {0x7F7F, 0x7F7F}, 2 }, 124 { __LINE__, {0x600,0xA00}, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, MB_ERR_INVALID_CHARS, "\xC0\xC0\x80", 4, 1, {0xFFFD, 0x7F7F}, 2 }, 125 { __LINE__, {0x000,0x502}, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, MB_ERR_INVALID_CHARS, "\xE0\xC0", 3, 1, {0x7F7F, 0x7F7F}, 2 }, 126 { __LINE__, {0x600,0xA00}, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, MB_ERR_INVALID_CHARS, "\xE0\xC0", 3, 1, {0xFFFD, 0x7F7F}, 2 }, 127 { __LINE__, {0x502,0x502}, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, MB_ERR_INVALID_CHARS, "\xE0\x20\xC0", 4, 1, {0x0020, 0x7F7F}, 2 }, 128 { __LINE__, {0x600,0xA00}, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, MB_ERR_INVALID_CHARS, "\xE0\x20\xC0", 4, 1, {0xFFFD, 0x7F7F}, 2 }, 129 { __LINE__, {0x000,0x502}, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, MB_ERR_INVALID_CHARS, "\x82\xA0\x82\xA2", -1, 1, {0x7F7F, 0x7F7F}, 2 }, 130 { __LINE__, {0x600,0xA00}, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, MB_ERR_INVALID_CHARS, "\x82\xA0\x82\xA2", -1, 1, {0xFFFD, 0x7F7F}, 2 }, 131 { __LINE__, {0x000,0x502}, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, MB_ERR_INVALID_CHARS, "\x82\xA0\x82\xA2\x82", -1, 1, {0x7F7F, 0x7F7F}, 2 }, 132 { __LINE__, {0x600,0xA00}, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, MB_ERR_INVALID_CHARS, "\x82\xA0\x82\xA2\x82", -1, 1, {0xFFFD, 0x7F7F}, 2 }, 133 /* Japanese UTF-8 without buffer */ 134 { __LINE__, {0x000,0xA00}, 4, 0xBEAF, CP_UTF8, 0, UTF8_Japanese, sizeof(UTF8_Japanese) }, 135 { __LINE__, {0x000,0xA00}, 4, 0xBEAF, CP_UTF8, MB_ERR_INVALID_CHARS, UTF8_Japanese, sizeof(UTF8_Japanese) }, 136 /* Japanese UTF-8 with buffer */ 137 { __LINE__, {0x000,0xA00}, 4, 0xBEAF, CP_UTF8, 0, UTF8_Japanese, sizeof(UTF8_Japanese), 4, {0x65E5, 0x672C, 0x8A9E, 0, 0x7F7F}, 5 }, 138 { __LINE__, {0x000,0xA00}, 4, 0xBEAF, CP_UTF8, MB_ERR_INVALID_CHARS, UTF8_Japanese, sizeof(UTF8_Japanese), 4, {0x65E5, 0x672C, 0x8A9E, 0, 0x7F7F}, 5 }, 139 /* Japanese UTF-8 with short buffer */ 140 { __LINE__, {0x000,0xA00}, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, 0, UTF8_Japanese, sizeof(UTF8_Japanese), 1, {0x65E5, 0x7F7F}, 2 }, 141 { __LINE__, {0x000,0xA00}, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, MB_ERR_INVALID_CHARS, UTF8_Japanese, sizeof(UTF8_Japanese), 1, {0x65E5, 0x7F7F}, 2 }, 142 /* Japanese UTF-8 truncated source */ 143 { __LINE__, {0x502,0x502}, 0, ERROR_SUCCESS, CP_UTF8, 0, UTF8_Japanese, 1, 4, {0x7F7F, 0x7F7F}, 2 }, 144 { __LINE__, {0x600,0xA00}, 1, 0xBEAF, CP_UTF8, 0, UTF8_Japanese, 1, 4, {0xFFFD, 0x7F7F}, 2 }, 145 { __LINE__, {0x502,0x502}, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, MB_ERR_INVALID_CHARS, UTF8_Japanese, 1, 4, {0x7F7F, 0x7F7F}, 2 }, 146 { __LINE__, {0x600,0xA00}, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, MB_ERR_INVALID_CHARS, UTF8_Japanese, 1, 4, {0xFFFD, 0x7F7F}, 2 }, 147 /* Japanese CP932 without buffer */ 148 { __LINE__, {0x000,0xA00}, 4, 0xBEAF, CP932, 0, SJIS_Japanese, sizeof(SJIS_Japanese) }, 149 { __LINE__, {0x000,0xA00}, 4, 0xBEAF, CP932, MB_ERR_INVALID_CHARS, SJIS_Japanese, sizeof(SJIS_Japanese) }, 150 /* Japanese CP932 with buffer */ 151 { __LINE__, {0x000,0xA00}, 4, 0xBEAF, CP932, 0, SJIS_Japanese, sizeof(SJIS_Japanese), 4, {0x65E5, 0x672C, 0x8A9E, 0, 0x7F7F}, 5 }, 152 { __LINE__, {0x000,0xA00}, 4, 0xBEAF, CP932, MB_ERR_INVALID_CHARS, SJIS_Japanese, sizeof(SJIS_Japanese), 4, {0x65E5, 0x672C, 0x8A9E, 0, 0x7F7F}, 5 }, 153 /* Japanese CP932 with short buffer */ 154 { __LINE__, {0x000,0xA00}, 0, ERROR_INSUFFICIENT_BUFFER, CP932, 0, SJIS_Japanese, sizeof(SJIS_Japanese), 1, {0x65E5, 0x7F7F}, 2 }, 155 { __LINE__, {0x000,0xA00}, 0, ERROR_INSUFFICIENT_BUFFER, CP932, MB_ERR_INVALID_CHARS, SJIS_Japanese, sizeof(SJIS_Japanese), 1, {0x65E5, 0x7F7F}, 2 }, 156 /* Japanese CP932 truncated source */ 157 { __LINE__, {0x000,0x502}, 1, 0xBEAF, CP932, 0, SJIS_Japanese, 1, 4, {0, 0x7F7F}, 2 }, 158 { __LINE__, {0x600,0xA00}, 1, 0xBEAF, CP932, 0, SJIS_Japanese, 1, 4, {0x30FB, 0x7F7F}, 2 }, 159 { __LINE__, {0x000,0xA00}, 0, ERROR_NO_UNICODE_TRANSLATION, CP932, MB_ERR_INVALID_CHARS, SJIS_Japanese, 1, 4, {0x7F7F, 0x7F7F}, 2 }, 160 /* invalid 5-byte UTF-8 sequences */ 161 { __LINE__, {0x502,0x502}, 0, ERROR_SUCCESS, CP_UTF8, 0, "\xF8\xA3\xA3\xA3\xA3", 1, 8, {0x7F7F, 0x7F7F}, 2 }, 162 { __LINE__, {0x600,0xA00}, 1, 0xBEAF, CP_UTF8, 0, "\xF8\xA3\xA3\xA3\xA3", 1, 8, {0xFFFD, 0x7F7F}, 2 }, 163 { __LINE__, {0x502,0x502}, 0, ERROR_SUCCESS, CP_UTF8, 0, "\xF8\xA3\xA3\xA3\xA3", 2, 8, {0x7F7F, 0x7F7F, 0x7F7F}, 3 }, 164 { __LINE__, {0x600,0xA00}, 2, 0xBEAF, CP_UTF8, 0, "\xF8\xA3\xA3\xA3\xA3", 2, 8, {0xFFFD, 0xFFFD, 0x7F7F}, 3 }, 165 { __LINE__, {0x502,0x502}, 0, ERROR_SUCCESS, CP_UTF8, 0, "\xF8\xA3\xA3\xA3\xA3", 3, 8, {0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F}, 4 }, 166 { __LINE__, {0x600,0xA00}, 3, 0xBEAF, CP_UTF8, 0, "\xF8\xA3\xA3\xA3\xA3", 3, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0x7F7F}, 4 }, 167 { __LINE__, {0x502,0x502}, 0, ERROR_SUCCESS, CP_UTF8, 0, "\xF8\xA3\xA3\xA3\xA3", 4, 8, {0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F}, 5 }, 168 { __LINE__, {0x600,0xA00}, 4, 0xBEAF, CP_UTF8, 0, "\xF8\xA3\xA3\xA3\xA3", 4, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x7F7F}, 5 }, 169 { __LINE__, {0x502,0x502}, 0, ERROR_SUCCESS, CP_UTF8, 0, "\xF8\xA3\xA3\xA3\xA3", 5, 8, {0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F}, 6 }, 170 { __LINE__, {0x600,0xA00}, 5, 0xBEAF, CP_UTF8, 0, "\xF8\xA3\xA3\xA3\xA3", 5, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x7F7F}, 6 }, 171 { __LINE__, {0x000,0x502}, 1, 0xBEAF, CP_UTF8, 0, "\xF8\xA3\xA3\xA3\xA3", 6, 8, {0, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F}, 6 }, 172 { __LINE__, {0x600,0xA00}, 6, 0xBEAF, CP_UTF8, 0, "\xF8\xA3\xA3\xA3\xA3", 6, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0}, 6 }, 173 /* invalid 6-byte UTF-8 sequences */ 174 { __LINE__, {0x502,0x502}, 0, ERROR_SUCCESS, CP_UTF8, 0, "\xFC\xA3\xA3\xA3\xA3\xA3", 1, 8, {0x7F7F, 0x7F7F}, 2 }, 175 { __LINE__, {0x600,0xA00}, 1, 0xBEAF, CP_UTF8, 0, "\xFC\xA3\xA3\xA3\xA3\xA3", 1, 8, {0xFFFD, 0x7F7F}, 2 }, 176 { __LINE__, {0x502,0x502}, 0, ERROR_SUCCESS, CP_UTF8, 0, "\xFC\xA3\xA3\xA3\xA3\xA3", 2, 8, {0x7F7F, 0x7F7F, 0x7F7F}, 3 }, 177 { __LINE__, {0x600,0xA00}, 2, 0xBEAF, CP_UTF8, 0, "\xFC\xA3\xA3\xA3\xA3\xA3", 2, 8, {0xFFFD, 0xFFFD, 0x7F7F}, 3 }, 178 { __LINE__, {0x502,0x502}, 0, ERROR_SUCCESS, CP_UTF8, 0, "\xFC\xA3\xA3\xA3\xA3\xA3", 3, 8, {0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F}, 4 }, 179 { __LINE__, {0x600,0xA00}, 3, 0xBEAF, CP_UTF8, 0, "\xFC\xA3\xA3\xA3\xA3\xA3", 3, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0x7F7F}, 4 }, 180 { __LINE__, {0x502,0x502}, 0, ERROR_SUCCESS, CP_UTF8, 0, "\xFC\xA3\xA3\xA3\xA3\xA3", 4, 8, {0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F}, 5 }, 181 { __LINE__, {0x600,0xA00}, 4, 0xBEAF, CP_UTF8, 0, "\xFC\xA3\xA3\xA3\xA3\xA3", 4, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x7F7F}, 5 }, 182 { __LINE__, {0x502,0x502}, 0, ERROR_SUCCESS, CP_UTF8, 0, "\xFC\xA3\xA3\xA3\xA3\xA3", 5, 8, {0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F}, 6 }, 183 { __LINE__, {0x600,0xA00}, 5, 0xBEAF, CP_UTF8, 0, "\xFC\xA3\xA3\xA3\xA3\xA3", 5, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x7F7F}, 6 }, 184 { __LINE__, {0x502,0x502}, 0, ERROR_SUCCESS, CP_UTF8, 0, "\xFC\xA3\xA3\xA3\xA3\xA3", 6, 8, {0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F}, 7 }, 185 { __LINE__, {0x600,0xA00}, 6, 0xBEAF, CP_UTF8, 0, "\xFC\xA3\xA3\xA3\xA3\xA3", 6, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x7F7F}, 7 }, 186 { __LINE__, {0x000,0x502}, 1, 0xBEAF, CP_UTF8, 0, "\xFC\xA3\xA3\xA3\xA3\xA3", 7, 8, {0, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F}, 7 }, 187 { __LINE__, {0x600,0xA00}, 7, 0xBEAF, CP_UTF8, 0, "\xFC\xA3\xA3\xA3\xA3\xA3", 7, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0}, 7 }, 188 /* invalid 7-byte UTF-8 sequences */ 189 { __LINE__, {0x502,0x502}, 0, ERROR_SUCCESS, CP_UTF8, 0, "\xFE\xA3\xA3\xA3\xA3\xA3\xA3", 1, 8, {0x7F7F, 0x7F7F}, 2 }, 190 { __LINE__, {0x600,0xA00}, 1, 0xBEAF, CP_UTF8, 0, "\xFE\xA3\xA3\xA3\xA3\xA3\xA3", 1, 8, {0xFFFD, 0x7F7F}, 2 }, 191 { __LINE__, {0x502,0x502}, 0, ERROR_SUCCESS, CP_UTF8, 0, "\xFE\xA3\xA3\xA3\xA3\xA3\xA3", 2, 8, {0x7F7F, 0x7F7F, 0x7F7F}, 3 }, 192 { __LINE__, {0x600,0xA00}, 2, 0xBEAF, CP_UTF8, 0, "\xFE\xA3\xA3\xA3\xA3\xA3\xA3", 2, 8, {0xFFFD, 0xFFFD, 0x7F7F}, 3 }, 193 { __LINE__, {0x502,0x502}, 0, ERROR_SUCCESS, CP_UTF8, 0, "\xFE\xA3\xA3\xA3\xA3\xA3\xA3", 3, 8, {0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F}, 4 }, 194 { __LINE__, {0x600,0xA00}, 3, 0xBEAF, CP_UTF8, 0, "\xFE\xA3\xA3\xA3\xA3\xA3\xA3", 3, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0x7F7F}, 4 }, 195 { __LINE__, {0x502,0x502}, 0, ERROR_SUCCESS, CP_UTF8, 0, "\xFE\xA3\xA3\xA3\xA3\xA3\xA3", 4, 8, {0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F}, 5 }, 196 { __LINE__, {0x600,0xA00}, 4, 0xBEAF, CP_UTF8, 0, "\xFE\xA3\xA3\xA3\xA3\xA3\xA3", 4, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x7F7F}, 5 }, 197 { __LINE__, {0x502,0x502}, 0, ERROR_SUCCESS, CP_UTF8, 0, "\xFE\xA3\xA3\xA3\xA3\xA3\xA3", 5, 8, {0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F}, 6 }, 198 { __LINE__, {0x600,0xA00}, 5, 0xBEAF, CP_UTF8, 0, "\xFE\xA3\xA3\xA3\xA3\xA3\xA3", 5, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x7F7F}, 6 }, 199 { __LINE__, {0x502,0x502}, 0, ERROR_SUCCESS, CP_UTF8, 0, "\xFE\xA3\xA3\xA3\xA3\xA3\xA3", 6, 8, {0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F}, 7 }, 200 { __LINE__, {0x600,0xA00}, 6, 0xBEAF, CP_UTF8, 0, "\xFE\xA3\xA3\xA3\xA3\xA3\xA3", 6, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x7F7F}, 7 }, 201 { __LINE__, {0x502,0x502}, 0, ERROR_SUCCESS, CP_UTF8, 0, "\xFE\xA3\xA3\xA3\xA3\xA3\xA3", 7, 8, {0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F}, 8 }, 202 { __LINE__, {0x600,0xA00}, 7, 0xBEAF, CP_UTF8, 0, "\xFE\xA3\xA3\xA3\xA3\xA3\xA3", 7, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x7F7F}, 8 }, 203 { __LINE__, {0x000,0x502}, 1, 0xBEAF, CP_UTF8, 0, "\xFE\xA3\xA3\xA3\xA3\xA3\xA3", 8, 8, {0, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F}, 8 }, 204 { __LINE__, {0x600,0xA00}, 8, 0xBEAF, CP_UTF8, 0, "\xFE\xA3\xA3\xA3\xA3\xA3\xA3", 8, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0}, 8 }, 205 /* invalid UTF-8 sequences */ 206 { __LINE__, {0x502,0x502}, 0, ERROR_SUCCESS, CP_UTF8, 0, "\xFF\xA3\xA3\xA3\xA3\xA3\xA3\xA3", 1, 8, {0x7F7F, 0x7F7F}, 2 }, 207 { __LINE__, {0x600,0xA00}, 1, 0xBEAF, CP_UTF8, 0, "\xFF\xA3\xA3\xA3\xA3\xA3\xA3\xA3", 1, 8, {0xFFFD, 0x7F7F}, 2 }, 208 { __LINE__, {0x502,0x502}, 0, ERROR_SUCCESS, CP_UTF8, 0, "\xFF\xA3\xA3\xA3\xA3\xA3\xA3\xA3", 2, 8, {0x7F7F, 0x7F7F, 0x7F7F}, 3 }, 209 { __LINE__, {0x600,0xA00}, 2, 0xBEAF, CP_UTF8, 0, "\xFF\xA3\xA3\xA3\xA3\xA3\xA3\xA3", 2, 8, {0xFFFD, 0xFFFD, 0x7F7F}, 3 }, 210 { __LINE__, {0x502,0x502}, 0, ERROR_SUCCESS, CP_UTF8, 0, "\xFF\xA3\xA3\xA3\xA3\xA3\xA3\xA3", 3, 8, {0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F}, 4 }, 211 { __LINE__, {0x600,0xA00}, 3, 0xBEAF, CP_UTF8, 0, "\xFF\xA3\xA3\xA3\xA3\xA3\xA3\xA3", 3, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0x7F7F}, 4 }, 212 { __LINE__, {0x502,0x502}, 0, ERROR_SUCCESS, CP_UTF8, 0, "\xFF\xA3\xA3\xA3\xA3\xA3\xA3\xA3", 4, 8, {0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F}, 5 }, 213 { __LINE__, {0x600,0xA00}, 4, 0xBEAF, CP_UTF8, 0, "\xFF\xA3\xA3\xA3\xA3\xA3\xA3\xA3", 4, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x7F7F}, 5 }, 214 { __LINE__, {0x502,0x502}, 0, ERROR_SUCCESS, CP_UTF8, 0, "\xFF\xA3\xA3\xA3\xA3\xA3\xA3\xA3", 5, 8, {0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F}, 6 }, 215 { __LINE__, {0x600,0xA00}, 5, 0xBEAF, CP_UTF8, 0, "\xFF\xA3\xA3\xA3\xA3\xA3\xA3\xA3", 5, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x7F7F}, 6 }, 216 { __LINE__, {0x502,0x502}, 0, ERROR_SUCCESS, CP_UTF8, 0, "\xFF\xA3\xA3\xA3\xA3\xA3\xA3\xA3", 6, 8, {0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F}, 7 }, 217 { __LINE__, {0x600,0xA00}, 6, 0xBEAF, CP_UTF8, 0, "\xFF\xA3\xA3\xA3\xA3\xA3\xA3\xA3", 6, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x7F7F}, 7 }, 218 { __LINE__, {0x502,0x502}, 0, ERROR_SUCCESS, CP_UTF8, 0, "\xFF\xA3\xA3\xA3\xA3\xA3\xA3\xA3", 7, 8, {0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F}, 8 }, 219 { __LINE__, {0x600,0xA00}, 7, 0xBEAF, CP_UTF8, 0, "\xFF\xA3\xA3\xA3\xA3\xA3\xA3\xA3", 7, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x7F7F}, 8 }, 220 { __LINE__, {0x502,0x502}, 0, ERROR_SUCCESS, CP_UTF8, 0, "\xFF\xA3\xA3\xA3\xA3\xA3\xA3\xA3", 8, 8, {0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F}, 9 }, 221 { __LINE__, {0x600,0xA00}, 8, 0xBEAF, CP_UTF8, 0, "\xFF\xA3\xA3\xA3\xA3\xA3\xA3\xA3", 8, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x7F7F}, 9 }, 222 { __LINE__, {0x000,0x502}, 1, 0xBEAF, CP_UTF8, 0, "\xFF\xA3\xA3\xA3\xA3\xA3\xA3\xA3", 9, 8, {0, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F, 0x7F7F}, 9 }, 223 { __LINE__, {0x600,0xA00}, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, 0, "\xFF\xA3\xA3\xA3\xA3\xA3\xA3\xA3", 9, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x7F7F}, 9 }, 224 }; 225 226 static void TestEntry(const ENTRY *pEntry) 227 { 228 int ret, i; 229 WCHAR Buffer[MAX_BUFFER]; 230 DWORD Error; 231 232 if ((OsVersion < pEntry->VersionRange[0]) || 233 (OsVersion > pEntry->VersionRange[1])) 234 { 235 skip("Skipping entry from line %u (Version range %lx-%lx, current %lx)\n", 236 pEntry->LineNo, 237 pEntry->VersionRange[0], 238 pEntry->VersionRange[1], 239 OsVersion); 240 return; 241 } 242 243 FillMemory(Buffer, sizeof(Buffer), 0x7F); 244 SetLastError(0xBEAF); 245 246 if (pEntry->DestLen == 0) 247 { 248 /* dest is NULL */ 249 ret = MultiByteToWideChar(pEntry->CodePage, pEntry->Flags, pEntry->Src, 250 pEntry->SrcLen, NULL, 0); 251 } 252 else 253 { 254 ok(pEntry->DestLen >= pEntry->CheckLen - 1, 255 "Line %d: DestLen was shorter than (CheckLen - 1)\n", pEntry->LineNo); 256 257 if (pEntry->SamePointer) 258 { 259 /* src ptr == dest ptr */ 260 ret = MultiByteToWideChar(pEntry->CodePage, pEntry->Flags, 261 (const char *)Buffer, pEntry->SrcLen, 262 Buffer, pEntry->DestLen); 263 } 264 else 265 { 266 /* src ptr != dest ptr */ 267 ret = MultiByteToWideChar(pEntry->CodePage, pEntry->Flags, 268 pEntry->Src, pEntry->SrcLen, 269 Buffer, pEntry->DestLen); 270 } 271 } 272 273 Error = GetLastError(); 274 275 /* check ret */ 276 ok(ret == pEntry->Return, "Line %d: ret expected %d, got %d\n", 277 pEntry->LineNo, pEntry->Return, ret); 278 279 /* check error code */ 280 ok(Error == pEntry->Error, 281 "Line %d: Wrong last error. Expected %lu, got %lu\n", 282 pEntry->LineNo, pEntry->Error, Error); 283 284 if (pEntry->DestLen) 285 { 286 /* check buffer */ 287 for (i = 0; i < pEntry->CheckLen; ++i) 288 { 289 ok(Buffer[i] == pEntry->CheckDest[i], "Line %d: Buffer[%d] expected %d, got %d\n", 290 pEntry->LineNo, i, pEntry->CheckDest[i], Buffer[i]); 291 } 292 } 293 } 294 295 START_TEST(MultiByteToWideChar) 296 { 297 RTL_OSVERSIONINFOW vi; 298 size_t i; 299 300 vi.dwOSVersionInfoSize = sizeof(vi); 301 if (RtlGetVersion(&vi) < 0) 302 { 303 skip("Failed to get OS version!\n"); 304 return; 305 } 306 307 OsVersion = (vi.dwMajorVersion << 8) | vi.dwMinorVersion; 308 309 /* NOTE: We use Win10's MultiByteToWideChar behaviour due to security reason. */ 310 if (IsReactOS()) 311 OsVersion = 0xa00; 312 313 for (i = 0; i < _countof(Entries); ++i) 314 { 315 TestEntry(&Entries[i]); 316 } 317 } 318