1 /* 2 * PROJECT: ReactOS api tests 3 * LICENSE: GPLv2+ - See COPYING in the top level directory 4 * PURPOSE: Tests for (Rtl)IsTextUnicode. 5 * PROGRAMMERS: Hermes Belusca-Maito 6 * Dmitry Chapyshev 7 * Katayama Hirofumi MZ 8 */ 9 10 #include "precomp.h" 11 12 #include <stdio.h> 13 14 PVOID LoadCodePageData(ULONG Code) 15 { 16 char filename[MAX_PATH], sysdir[MAX_PATH]; 17 HANDLE hFile; 18 PVOID Data = NULL; 19 GetSystemDirectoryA(sysdir, MAX_PATH); 20 21 if (Code != -1) 22 StringCbPrintfA(filename, sizeof(filename), "%s\\c_%lu.nls", sysdir, Code); 23 else 24 StringCbPrintfA(filename, sizeof(filename), "%s\\l_intl.nls", sysdir); 25 26 hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); 27 if (hFile != INVALID_HANDLE_VALUE) 28 { 29 DWORD dwRead; 30 DWORD dwFileSize = GetFileSize(hFile, NULL); 31 Data = malloc(dwFileSize); 32 ReadFile(hFile, Data, dwFileSize, &dwRead, NULL); 33 CloseHandle(hFile); 34 } 35 return Data; 36 } 37 38 /* https://www.microsoft.com/resources/msdn/goglobal/default.mspx */ 39 void SetupLocale(ULONG AnsiCode, ULONG OemCode, ULONG Unicode) 40 { 41 NLSTABLEINFO NlsTable; 42 PVOID AnsiCodePageData; 43 PVOID OemCodePageData; 44 PVOID UnicodeCaseTableData; 45 46 AnsiCodePageData = LoadCodePageData(AnsiCode); 47 OemCodePageData = LoadCodePageData(OemCode); 48 UnicodeCaseTableData = LoadCodePageData(Unicode); 49 50 RtlInitNlsTables(AnsiCodePageData, OemCodePageData, UnicodeCaseTableData, &NlsTable); 51 RtlResetRtlTranslations(&NlsTable); 52 /* Do NOT free the buffers here, they are directly used! 53 Yes, we leak the old buffers, but this is a test anyway... */ 54 55 } 56 57 START_TEST(IsTextUnicode) 58 { 59 #define INVALID_FLAG 0xFFFFFFFF 60 61 #define NEW_TEST(Buffer, Flags, ResultFlags, Success) \ 62 { __LINE__, (PVOID)(Buffer), sizeof((Buffer)), (Flags), (ResultFlags), (Success) } 63 64 static struct 65 { 66 INT lineno; 67 68 /* Input */ 69 PVOID Buffer; 70 INT Size; 71 INT Flags; 72 73 /* Output */ 74 INT ResultFlags; 75 BOOL Success; 76 } Tests[] = 77 { 78 /* ANSI string */ 79 NEW_TEST("ANSI string", IS_TEXT_UNICODE_ASCII16, 0, FALSE), 80 NEW_TEST("ANSI string", IS_TEXT_UNICODE_STATISTICS, 0, FALSE), 81 NEW_TEST("ANSI string", INVALID_FLAG, 0, FALSE), 82 83 /* UNICODE strings */ 84 NEW_TEST(L"a", IS_TEXT_UNICODE_ASCII16, IS_TEXT_UNICODE_ASCII16, TRUE), 85 NEW_TEST(L"a", IS_TEXT_UNICODE_UNICODE_MASK, IS_TEXT_UNICODE_STATISTICS | IS_TEXT_UNICODE_ASCII16, TRUE), 86 NEW_TEST(L"a", IS_TEXT_UNICODE_STATISTICS, IS_TEXT_UNICODE_STATISTICS, TRUE), 87 NEW_TEST(L"a", INVALID_FLAG, 0, TRUE), 88 89 NEW_TEST(L"UNICODE String 0", IS_TEXT_UNICODE_ASCII16, 0, FALSE), 90 NEW_TEST(L"UNICODE String 0", IS_TEXT_UNICODE_UNICODE_MASK, IS_TEXT_UNICODE_CONTROLS | IS_TEXT_UNICODE_STATISTICS, TRUE), 91 NEW_TEST(L"UNICODE String 0", IS_TEXT_UNICODE_STATISTICS, IS_TEXT_UNICODE_STATISTICS, TRUE), 92 NEW_TEST(L"UNICODE String 0", INVALID_FLAG, 0, TRUE), 93 94 NEW_TEST(L"\xFEFF" L"UNICODE String 1", IS_TEXT_UNICODE_ASCII16, 0, FALSE), 95 NEW_TEST(L"\xFEFF" L"UNICODE String 1", IS_TEXT_UNICODE_UNICODE_MASK, IS_TEXT_UNICODE_SIGNATURE | IS_TEXT_UNICODE_CONTROLS, TRUE), 96 NEW_TEST(L"\xFEFF" L"UNICODE String 1", IS_TEXT_UNICODE_STATISTICS, 0, FALSE), 97 NEW_TEST(L"\xFEFF" L"UNICODE String 1", INVALID_FLAG, 0, TRUE), 98 99 NEW_TEST(L"\xFFFE" L"UNICODE String 2", IS_TEXT_UNICODE_ASCII16, 0, FALSE), 100 NEW_TEST(L"\xFFFE" L"UNICODE String 2", IS_TEXT_UNICODE_UNICODE_MASK, IS_TEXT_UNICODE_CONTROLS, TRUE), 101 NEW_TEST(L"\xFFFE" L"UNICODE String 2", IS_TEXT_UNICODE_STATISTICS, 0, FALSE), 102 NEW_TEST(L"\xFFFE" L"UNICODE String 2", INVALID_FLAG, 0, FALSE), 103 104 NEW_TEST(L"UNICODE String 3 Привет!", IS_TEXT_UNICODE_ASCII16, 0, FALSE), 105 NEW_TEST(L"UNICODE String 3 Привет!", IS_TEXT_UNICODE_UNICODE_MASK, IS_TEXT_UNICODE_CONTROLS | IS_TEXT_UNICODE_STATISTICS, TRUE), 106 NEW_TEST(L"UNICODE String 3 Привет!", IS_TEXT_UNICODE_STATISTICS, IS_TEXT_UNICODE_STATISTICS, TRUE), 107 NEW_TEST(L"UNICODE String 3 Привет!", INVALID_FLAG, 0, TRUE), 108 109 NEW_TEST(L"\xFEFF" L"UNICODE String 4 Привет!", IS_TEXT_UNICODE_ASCII16, 0, FALSE), 110 NEW_TEST(L"\xFEFF" L"UNICODE String 4 Привет!", IS_TEXT_UNICODE_UNICODE_MASK, IS_TEXT_UNICODE_SIGNATURE | IS_TEXT_UNICODE_CONTROLS, TRUE), 111 NEW_TEST(L"\xFEFF" L"UNICODE String 4 Привет!", IS_TEXT_UNICODE_STATISTICS, 0, FALSE), 112 NEW_TEST(L"\xFEFF" L"UNICODE String 4 Привет!", INVALID_FLAG, 0, TRUE), 113 114 NEW_TEST(L"\xFFFE" L"UNICODE String 5 Привет!", IS_TEXT_UNICODE_ASCII16, 0, FALSE), 115 NEW_TEST(L"\xFFFE" L"UNICODE String 5 Привет!", IS_TEXT_UNICODE_UNICODE_MASK, IS_TEXT_UNICODE_CONTROLS, TRUE), 116 NEW_TEST(L"\xFFFE" L"UNICODE String 5 Привет!", IS_TEXT_UNICODE_STATISTICS, 0, FALSE), 117 NEW_TEST(L"\xFFFE" L"UNICODE String 5 Привет!", INVALID_FLAG, 0, FALSE), 118 119 /* Reverse BOM */ 120 NEW_TEST(L"UNICODE S" L"\xFFFE" L"tring 5 Привет!", IS_TEXT_UNICODE_ILLEGAL_CHARS, IS_TEXT_UNICODE_ILLEGAL_CHARS, FALSE), 121 /* UNICODE_NUL */ 122 NEW_TEST(L"UNICODE S" L"\x0000" L"tring 5 Привет!", IS_TEXT_UNICODE_ILLEGAL_CHARS, IS_TEXT_UNICODE_ILLEGAL_CHARS, FALSE), 123 /* ASCII CRLF (packed into one word) */ 124 NEW_TEST(L"UNICODE S" L"\x0A0D" L"tring 5 Привет!", IS_TEXT_UNICODE_ILLEGAL_CHARS, IS_TEXT_UNICODE_ILLEGAL_CHARS, FALSE), 125 /* Unicode 0xFFFF */ 126 NEW_TEST(L"UNICODE S" L"\xFFFF" L"tring 5 Привет!", IS_TEXT_UNICODE_ILLEGAL_CHARS, IS_TEXT_UNICODE_ILLEGAL_CHARS, FALSE), 127 128 NEW_TEST(L"UNICODE String 0", IS_TEXT_UNICODE_DBCS_LEADBYTE, 0, FALSE) 129 }; 130 131 const char japanese_with_lead[] = "ABC" "\x83\x40" "D"; 132 const char japanese_sjis[] = "\x93\xFA\x96\x7B\x8C\xEA\x31\x32\x33\x93\xFA\x96\x7B\x8C\xEA"; 133 const char japanese_utf8[] = "\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E\x31\x32\x33\xE6\x97\xA5" 134 "\xE6\x9C\xAC\xE8\xAA\x9E"; 135 const char simplfied_chinese_with_lead[] = "ABC" "\xC5\xC5" "D"; 136 const char korean_with_lead[] = "ABC" "\xBF\xAD" "D"; 137 const char traditional_chinese_with_lead[] = "ABC" "\xB1\xC1" "D"; 138 139 UINT i; 140 BOOL Success; 141 INT Result; 142 143 for (i = 0; i < ARRAYSIZE(Tests); ++i) 144 { 145 Result = Tests[i].Flags; 146 Success = IsTextUnicode(Tests[i].Buffer, Tests[i].Size, ((Result != INVALID_FLAG) ? &Result : NULL)); 147 ok(Success == Tests[i].Success, "Line %u: IsTextUnicode() returned 0x%x, expected %s\n", Tests[i].lineno, Success, (Tests[i].Success ? "TRUE" : "FALSE")); 148 if (Result != INVALID_FLAG) 149 ok(Result == Tests[i].ResultFlags, "Line %u: IsTextUnicode() Result returned 0x%x, expected 0x%x\n", Tests[i].lineno, Result, Tests[i].ResultFlags); 150 } 151 152 /* Japanese */ 153 SetupLocale(932, 932, -1); 154 155 Result = IS_TEXT_UNICODE_DBCS_LEADBYTE; 156 ok_int(IsTextUnicode(japanese_with_lead, sizeof(japanese_with_lead), &Result), FALSE); 157 ok_int(Result, IS_TEXT_UNICODE_DBCS_LEADBYTE); 158 159 ok_int(IsTextUnicode(japanese_sjis, sizeof(japanese_sjis) - 1, NULL), FALSE); 160 161 Result = IS_TEXT_UNICODE_STATISTICS | IS_TEXT_UNICODE_REVERSE_STATISTICS; 162 ok_int(IsTextUnicode(japanese_sjis, sizeof(japanese_sjis) - 1, &Result), FALSE); 163 ok_int(Result, 0); 164 165 Result = IS_TEXT_UNICODE_STATISTICS | IS_TEXT_UNICODE_REVERSE_STATISTICS | 166 IS_TEXT_UNICODE_DBCS_LEADBYTE; 167 ok_int(IsTextUnicode(japanese_sjis, sizeof(japanese_sjis) - 1, &Result), FALSE); 168 ok_int(Result, (IS_TEXT_UNICODE_DBCS_LEADBYTE | IS_TEXT_UNICODE_REVERSE_STATISTICS)); 169 170 ok_int(IsTextUnicode(japanese_utf8, sizeof(japanese_utf8) - 1, NULL), FALSE); 171 172 Result = IS_TEXT_UNICODE_STATISTICS | IS_TEXT_UNICODE_REVERSE_STATISTICS; 173 ok_int(IsTextUnicode(japanese_utf8, sizeof(japanese_utf8) - 1, &Result), FALSE); 174 ok_int(Result, 0); 175 176 Result = IS_TEXT_UNICODE_STATISTICS | IS_TEXT_UNICODE_REVERSE_STATISTICS | 177 IS_TEXT_UNICODE_DBCS_LEADBYTE; 178 ok_int(IsTextUnicode(japanese_utf8, sizeof(japanese_utf8) - 1, &Result), FALSE); 179 ok_int(Result, (IS_TEXT_UNICODE_DBCS_LEADBYTE | IS_TEXT_UNICODE_STATISTICS)); 180 181 /* Simplified Chinese */ 182 SetupLocale(936, 936, -1); 183 184 Result = IS_TEXT_UNICODE_DBCS_LEADBYTE; 185 ok(!IsTextUnicode(simplfied_chinese_with_lead, sizeof(simplfied_chinese_with_lead), &Result), "IsTextUnicode() returned TRUE, expected FALSE\n"); 186 ok(Result == IS_TEXT_UNICODE_DBCS_LEADBYTE, "Result returned 0x%x, expected 0x%x\n", Result, IS_TEXT_UNICODE_DBCS_LEADBYTE); 187 188 /* Korean */ 189 SetupLocale(949, 949, -1); 190 191 Result = IS_TEXT_UNICODE_DBCS_LEADBYTE; 192 ok(!IsTextUnicode(korean_with_lead, sizeof(korean_with_lead), &Result), "IsTextUnicode() returned TRUE, expected FALSE\n"); 193 ok(Result == IS_TEXT_UNICODE_DBCS_LEADBYTE, "Result returned 0x%x, expected 0x%x\n", Result, IS_TEXT_UNICODE_DBCS_LEADBYTE); 194 195 /* Traditional Chinese */ 196 SetupLocale(950, 950, -1); 197 198 Result = IS_TEXT_UNICODE_DBCS_LEADBYTE; 199 ok(!IsTextUnicode(traditional_chinese_with_lead, sizeof(traditional_chinese_with_lead), &Result), "IsTextUnicode() returned TRUE, expected FALSE\n"); 200 ok(Result == IS_TEXT_UNICODE_DBCS_LEADBYTE, "Result returned 0x%x, expected 0x%x\n", Result, IS_TEXT_UNICODE_DBCS_LEADBYTE); 201 } 202