1 /* Copyright 2020 Pierre Ossman <ossman@cendio.se> for Cendio AB
2  *
3  * This is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  *
8  * This software is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this software; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
16  * USA.
17  */
18 
19 #include <stdio.h>
20 #include <wchar.h>
21 
22 #include <rfb/util.h>
23 
24 struct _ucs4utf8 {
25     unsigned ucs4;
26     const char *utf8;
27 };
28 
29 struct _ucs4utf16 {
30     unsigned ucs4;
31     const wchar_t *utf16;
32 };
33 
34 struct _latin1utf8 {
35     const char *latin1;
36     const char *utf8;
37 };
38 
39 struct _utf8utf16 {
40     const char *utf8;
41     const wchar_t *utf16;
42 };
43 
44 struct _ucs4utf8 ucs4utf8[] = {
45     { 0x0061, "a" },
46     { 0x00f6, "\xc3\xb6" },
47     { 0x263a, "\xe2\x98\xba" },
48     { 0x1f638, "\xf0\x9f\x98\xb8" },
49     { 0x2d006, "\xf0\xad\x80\x86" },
50     { 0xfffd, "\xe5\xe4" },
51     { 0x110200, "\xef\xbf\xbd" },
52 };
53 
54 struct _ucs4utf16 ucs4utf16[] = {
55     { 0x0061, L"a" },
56     { 0x00f6, L"\xf6" },
57     { 0x263a, L"\x263a" },
58     { 0x1f638, L"\xd83d\xde38" },
59     { 0x2d006, L"\xd874\xdc06" },
60     { 0xfffd, L"\xdc40\xdc12" },
61     { 0x110200, L"\xfffd" },
62     { 0xd87f, L"\xfffd" },
63 };
64 
65 struct _latin1utf8 latin1utf8[] = {
66     { "abc",            "abc" },
67     { "\xe5\xe4\xf6",   "\xc3\xa5\xc3\xa4\xc3\xb6" },
68     { "???",            "\xe2\x98\xb9\xe2\x98\xba\xe2\x98\xbb" },
69     { "?",              "\xe5\xe4" },
70 };
71 
72 struct _utf8utf16 utf8utf16[] = {
73     { "abc",                                                L"abc" },
74     { "\xc3\xa5\xc3\xa4\xc3\xb6",                           L"\xe5\xe4\xf6" },
75     { "\xe2\x98\xb9\xe2\x98\xba\xe2\x98\xbb",               L"\x2639\x263a\x263b" },
76     { "\xf0\x9f\x98\xb8\xf0\x9f\x99\x81\xf0\x9f\x99\x82",   L"\xd83d\xde38\xd83d\xde41\xd83d\xde42" },
77     { "\xf0\xad\x80\x86\xf0\xad\x80\x88",                   L"\xd874\xdc06\xd874\xdc08" },
78     { "\xef\xbf\xbd\xc3\xa5",                               L"\xd840\xe5" },
79     { "\xed\xa1\xbf",                                       L"\xfffd" },
80 };
81 
82 #define ARRAY_SIZE(a) (sizeof(a)/sizeof(*a))
83 
main(int argc,char ** argv)84 int main(int argc, char** argv)
85 {
86     int failures;
87     size_t i;
88 
89     unsigned ucs4;
90     char utf8[5];
91     wchar_t utf16[3];
92     char *out;
93     wchar_t *wout;
94     size_t len;
95 
96     failures = 0;
97 
98     for (i = 0;i < ARRAY_SIZE(ucs4utf8);i++) {
99         /* Expected failure? */
100         if (ucs4utf8[i].ucs4 == 0xfffd)
101             continue;
102 
103         len = rfb::ucs4ToUTF8(ucs4utf8[i].ucs4, utf8);
104         if ((len != strlen(utf8)) ||
105             (strcmp(utf8, ucs4utf8[i].utf8) != 0)) {
106             printf("FAILED: ucs4ToUTF8() #%d\n", (int)i+1);
107             failures++;
108         }
109     }
110 
111     for (i = 0;i < ARRAY_SIZE(ucs4utf8);i++) {
112         /* Expected failure? */
113         if (strcmp(ucs4utf8[i].utf8, "\xef\xbf\xbd") == 0)
114             continue;
115 
116         len = rfb::utf8ToUCS4(ucs4utf8[i].utf8, strlen(ucs4utf8[i].utf8), &ucs4);
117         if ((len != strlen(ucs4utf8[i].utf8)) ||
118             (ucs4 != ucs4utf8[i].ucs4)) {
119             printf("FAILED: utf8ToUCS4() #%d\n", (int)i+1);
120             failures++;
121         }
122     }
123 
124     for (i = 0;i < ARRAY_SIZE(ucs4utf16);i++) {
125         /* Expected failure? */
126         if (ucs4utf16[i].ucs4 == 0xfffd)
127             continue;
128 
129         len = rfb::ucs4ToUTF16(ucs4utf16[i].ucs4, utf16);
130         if ((len != wcslen(utf16)) ||
131             (wcscmp(utf16, ucs4utf16[i].utf16) != 0)) {
132             printf("FAILED: ucs4ToUTF16() #%d\n", (int)i+1);
133             failures++;
134         }
135     }
136 
137     for (i = 0;i < ARRAY_SIZE(ucs4utf16);i++) {
138         /* Expected failure? */
139         if (wcscmp(ucs4utf16[i].utf16, L"\xfffd") == 0)
140             continue;
141 
142         len = rfb::utf16ToUCS4(ucs4utf16[i].utf16, wcslen(ucs4utf16[i].utf16), &ucs4);
143         if ((len != wcslen(ucs4utf16[i].utf16)) ||
144             (ucs4 != ucs4utf16[i].ucs4)) {
145             printf("FAILED: utf16ToUCS4() #%d\n", (int)i+1);
146             failures++;
147         }
148     }
149 
150     for (i = 0;i < ARRAY_SIZE(latin1utf8);i++) {
151         /* Expected failure? */
152         if (strchr(latin1utf8[i].latin1, '?') != NULL)
153             continue;
154 
155         out = rfb::latin1ToUTF8(latin1utf8[i].latin1);
156         if (strcmp(out, latin1utf8[i].utf8) != 0) {
157             printf("FAILED: latin1ToUTF8() #%d\n", (int)i+1);
158             failures++;
159         }
160         rfb::strFree(out);
161     }
162 
163     for (i = 0;i < ARRAY_SIZE(latin1utf8);i++) {
164         out = rfb::utf8ToLatin1(latin1utf8[i].utf8);
165         if (strcmp(out, latin1utf8[i].latin1) != 0) {
166             printf("FAILED: utf8ToLatin1() #%d\n", (int)i+1);
167             failures++;
168         }
169         rfb::strFree(out);
170     }
171 
172     for (i = 0;i < ARRAY_SIZE(utf8utf16);i++) {
173         /* Expected failure? */
174         if (wcscmp(utf8utf16[i].utf16, L"\xfffd") == 0)
175             continue;
176 
177         out = rfb::utf16ToUTF8(utf8utf16[i].utf16);
178         if (strcmp(out, utf8utf16[i].utf8) != 0) {
179             printf("FAILED: utf16ToUTF8() #%d\n", (int)i+1);
180             failures++;
181         }
182         rfb::strFree(out);
183     }
184 
185     for (i = 0;i < ARRAY_SIZE(utf8utf16);i++) {
186         /* Expected failure? */
187         if (strstr(utf8utf16[i].utf8, "\xef\xbf\xbd") != NULL)
188             continue;
189 
190         wout = rfb::utf8ToUTF16(utf8utf16[i].utf8);
191         if (wcscmp(wout, utf8utf16[i].utf16) != 0) {
192             printf("FAILED: utf8ToUTF16() #%d\n", (int)i+1);
193             failures++;
194         }
195         rfb::strFree(wout);
196     }
197 
198     if (failures == 0) {
199         printf("OK\n");
200     } else {
201         printf("FAIL: %d failures\n", failures);
202     }
203 
204     return 0;
205 }
206