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