Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : test suite for the charcnv functions
4 :
5 : Copyright (C) Andrew Bartlett 2011
6 :
7 : This program is free software; you can redistribute it and/or modify
8 : it under the terms of the GNU General Public License as published by
9 : the Free Software Foundation; either version 3 of the License, or
10 : (at your option) any later version.
11 :
12 : This program is distributed in the hope that it will be useful,
13 : but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : GNU General Public License for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with this program. If not, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #include "includes.h"
22 : #include "torture/torture.h"
23 : #include "lib/util/charset/charset.h"
24 : #include "param/param.h"
25 : #include "lib/util/base64.h"
26 :
27 : struct torture_suite *torture_local_convert_string_handle(TALLOC_CTX *mem_ctx);
28 : struct torture_suite *torture_local_string_case_handle(TALLOC_CTX *mem_ctx);
29 : struct torture_suite *torture_local_convert_string(TALLOC_CTX *mem_ctx);
30 : struct torture_suite *torture_local_string_case(TALLOC_CTX *mem_ctx);
31 :
32 : /* The text below is in ancient and a latin charset transliteration of
33 : * greek, and an english translation. It from Apology by Plato and sourced from
34 : * http://en.wikipedia.org/w/index.php?title=Ancient_Greek&oldid=421361065#Example_text
35 : */
36 :
37 : const char *plato_english_ascii =
38 : "What you, men of Athens, have learned from my accusers, I do not"
39 : " know: but I, for my part, nearly forgot who I was thanks to them since"
40 : " they spoke so persuasively. And yet, of the truth, they have spoken,"
41 : " one might say, nothing at all.";
42 :
43 : const char *plato_english_utf16le_base64 =
44 : "VwBoAGEAdAAgAHkAbwB1ACwAIABtAGUAbgAgAG8AZgAgAEEAdABoAGUAbgBzACwAIABoAGEAdgBl"
45 : "ACAAbABlAGEAcgBuAGUAZAAgAGYAcgBvAG0AIABtAHkAIABhAGMAYwB1AHMAZQByAHMALAAgAEkA"
46 : "IABkAG8AIABuAG8AdAAgAGsAbgBvAHcAOgAgAGIAdQB0ACAASQAsACAAZgBvAHIAIABtAHkAIABw"
47 : "AGEAcgB0ACwAIABuAGUAYQByAGwAeQAgAGYAbwByAGcAbwB0ACAAdwBoAG8AIABJACAAdwBhAHMA"
48 : "IAB0AGgAYQBuAGsAcwAgAHQAbwAgAHQAaABlAG0AIABzAGkAbgBjAGUAIAB0AGgAZQB5ACAAcwBw"
49 : "AG8AawBlACAAcwBvACAAcABlAHIAcwB1AGEAcwBpAHYAZQBsAHkALgAgAEEAbgBkACAAeQBlAHQA"
50 : "LAAgAG8AZgAgAHQAaABlACAAdAByAHUAdABoACwAIAB0AGgAZQB5ACAAaABhAHYAZQAgAHMAcABv"
51 : "AGsAZQBuACwAIABvAG4AZQAgAG0AaQBnAGgAdAAgAHMAYQB5ACwAIABuAG8AdABoAGkAbgBnACAA"
52 : "YQB0ACAAYQBsAGwALgA=";
53 :
54 : static const char *plato_utf8_base64 =
55 : "4b2Nz4TOuSDOvOG9ss69IOG9kc68zrXhv5bPgiwg4b2mIOG8hM69zrTPgc61z4IgzobOuM63zr3O"
56 : "seG/ls6/zrksIM+AzrXPgM+Mzr3OuM6xz4TOtSDhvZHPgOG9uCDPhOG/ts69IOG8kM684b+2zr0g"
57 : "zrrOsc+EzrfOs8+Mz4HPic69LCDOv+G9kM66IM6/4by2zrTOsTog4byQzrPhvbwgzrQnIM6/4b2W"
58 : "zr0gzrrOseG9tiDOseG9kM+E4b24z4Ig4b2Rz4AnIM6x4b2Qz4Thv7bOvSDhvYDOu86vzrPOv8+F"
59 : "IOG8kM68zrHPhc+Ezr/hv6Yg4byQz4DOtc67zrHOuM+MzrzOt869LCDOv+G9lc+Ez4kgz4DOuc64"
60 : "zrHOveG/ts+CIOG8lM67zrXOs86/zr0uIM6azrHOr8+Ezr/OuSDhvIDOu863zrjOrc+CIM6zzrUg"
61 : "4b2hz4Ig4byUz4DOv8+CIM614bywz4DOteG/ls69IM6/4b2QzrThvbLOvSDOteG8sM+Bzq7Ous6x"
62 : "z4POuc69Lg==";
63 :
64 : static const char *plato_utf16le_base64 =
65 : "TR/EA7kDIAC8A3IfvQMgAFEfvAO1A9YfwgMsACAAZh8gAAQfvQO0A8EDtQPCAyAAhgO4A7cDvQOx"
66 : "A9YfvwO5AywAIADAA7UDwAPMA70DuAOxA8QDtQMgAFEfwAN4HyAAxAP2H70DIAAQH7wD9h+9AyAA"
67 : "ugOxA8QDtwOzA8wDwQPJA70DLAAgAL8DUB+6AyAAvwM2H7QDsQM6ACAAEB+zA3wfIAC0AycAIAC/"
68 : "A1YfvQMgALoDsQN2HyAAsQNQH8QDeB/CAyAAUR/AAycAIACxA1AfxAP2H70DIABAH7sDrwOzA78D"
69 : "xQMgABAfvAOxA8UDxAO/A+YfIAAQH8ADtQO7A7EDuAPMA7wDtwO9AywAIAC/A1UfxAPJAyAAwAO5"
70 : "A7gDsQO9A/YfwgMgABQfuwO1A7MDvwO9Ay4AIACaA7EDrwPEA78DuQMgAAAfuwO3A7gDrQPCAyAA"
71 : "swO1AyAAYR/CAyAAFB/AA78DwgMgALUDMB/AA7UD1h+9AyAAvwNQH7QDch+9AyAAtQMwH8EDrgO6"
72 : "A7EDwwO5A70DLgA=";
73 :
74 : static const char *plato_latin_utf8_base64 =
75 : "SMOzdGkgbcOobiBodW1lw65zLCDDtCDDoW5kcmVzIEF0aMSTbmHDrm9pLCBwZXDDs250aGF0ZSBo"
76 : "dXDDsiB0w7RuIGVtw7RuIGthdMSTZ8OzcsWNbiwgb3VrIG/DrmRhOiBlZ+G5kSBkJyBvw7tuIGth"
77 : "w6wgYXV0w7JzIGh1cCcgYXV0xY1uIG9sw61nb3UgZW1hdXRvw7sgZXBlbGF0aMOzbcSTbiwgaG/D"
78 : "unTFjSBwaXRoYW7DtHMgw6lsZWdvbi4gS2HDrXRvaSBhbMSTdGjDqXMgZ2UgaMWNcyDDqXBvcyBl"
79 : "aXBlw65uIG91ZMOobiBlaXLhuJdrYXNpbi4=";
80 :
81 : static const char *plato_latin_utf16le_base64 =
82 : "SADzAHQAaQAgAG0A6ABuACAAaAB1AG0AZQDuAHMALAAgAPQAIADhAG4AZAByAGUAcwAgAEEAdABo"
83 : "ABMBbgBhAO4AbwBpACwAIABwAGUAcADzAG4AdABoAGEAdABlACAAaAB1AHAA8gAgAHQA9ABuACAA"
84 : "ZQBtAPQAbgAgAGsAYQB0ABMBZwDzAHIATQFuACwAIABvAHUAawAgAG8A7gBkAGEAOgAgAGUAZwBR"
85 : "HiAAZAAnACAAbwD7AG4AIABrAGEA7AAgAGEAdQB0APIAcwAgAGgAdQBwACcAIABhAHUAdABNAW4A"
86 : "IABvAGwA7QBnAG8AdQAgAGUAbQBhAHUAdABvAPsAIABlAHAAZQBsAGEAdABoAPMAbQATAW4ALAAg"
87 : "AGgAbwD6AHQATQEgAHAAaQB0AGgAYQBuAPQAcwAgAOkAbABlAGcAbwBuAC4AIABLAGEA7QB0AG8A"
88 : "aQAgAGEAbAATAXQAaADpAHMAIABnAGUAIABoAE0BcwAgAOkAcABvAHMAIABlAGkAcABlAO4AbgAg"
89 : "AG8AdQBkAOgAbgAgAGUAaQByABceawBhAHMAaQBuAC4A";
90 :
91 : static const char *gd_utf8_base64 = "R8O8bnRoZXIgRGVzY2huZXI=";
92 : static const char *gd_utf8_upper_base64 = "R8OcTlRIRVIgREVTQ0hORVI=";
93 : static const char *gd_utf8_lower_base64 = "Z8O8bnRoZXIgZGVzY2huZXI=";
94 : static const char *gd_cp850_base64 = "R4FudGhlciBEZXNjaG5lcg==";
95 : static const char *gd_cp850_upper_base64 = "R5pOVEhFUiBERVNDSE5FUg==";
96 : static const char *gd_cp850_lower_base64 = "Z4FudGhlciBkZXNjaG5lcg==";
97 : static const char *gd_iso8859_1_base64 = "R/xudGhlciBEZXNjaG5lcg==";
98 : static const char *gd_utf16le_base64 = "RwD8AG4AdABoAGUAcgAgAEQAZQBzAGMAaABuAGUAcgA=";
99 : /* täst */
100 : static const char *utf8_nfc_base64 = "dMOkc3QA";
101 : /* täst, where ä = a + combining diaeresis */
102 : static const char *utf8_nfd_base64 = "dGHMiHN0AA==";
103 :
104 : /*
105 : * These cp850 bytes correspond to high Unicode codes, stretching out to
106 : * 3-byte sequences in utf-8.
107 : */
108 : static const char *cp850_high_points = "\xb9\xba\xbb\xbc\xcd\xce";
109 : static const char *utf8_high_points = "╣║╗╝═╬";
110 :
111 2 : static bool test_cp850_high_points(struct torture_context *tctx)
112 : {
113 2 : struct smb_iconv_handle *iconv_handle = NULL;
114 2 : DATA_BLOB cp850 = data_blob_string_const(cp850_high_points);
115 2 : DATA_BLOB utf8;
116 2 : DATA_BLOB cp850_return;
117 :
118 2 : iconv_handle = get_iconv_testing_handle(tctx, "CP850", "UTF8",
119 2 : lpcfg_parm_bool(tctx->lp_ctx,
120 : NULL,
121 : "iconv",
122 : "use_builtin_handlers",
123 : true));
124 :
125 2 : torture_assert(tctx, iconv_handle, "creating iconv handle");
126 :
127 2 : torture_assert(tctx,
128 : convert_string_talloc_handle(tctx, iconv_handle,
129 : CH_DOS, CH_UTF8,
130 : cp850.data, cp850.length,
131 : (void *)&utf8.data, &utf8.length),
132 : "conversion from CP850 to UTF-8");
133 :
134 2 : torture_assert(tctx, utf8.length == cp850.length * 3,
135 : "CP850 high bytes expand to the right size");
136 :
137 2 : torture_assert(tctx,
138 : memcmp(utf8.data, utf8_high_points, utf8.length) == 0,
139 : "cp850 converted to utf8 matches expected value");
140 :
141 2 : torture_assert(tctx,
142 : convert_string_talloc_handle(tctx, iconv_handle,
143 : CH_UTF8, CH_DOS,
144 : utf8.data, utf8.length,
145 : (void *)&cp850_return.data,
146 : &cp850_return.length),
147 : "conversion from UTF-8 back to CP850");
148 :
149 2 : torture_assert(tctx, data_blob_cmp(&cp850_return, &cp850) == 0,
150 : "UTF-8 returned to CP850 matches the original");
151 0 : return true;
152 : }
153 :
154 :
155 2 : static bool test_gd_iso8859_cp850_handle(struct torture_context *tctx)
156 : {
157 2 : struct smb_iconv_handle *iconv_handle;
158 2 : DATA_BLOB gd_utf8 = base64_decode_data_blob(gd_utf8_base64);
159 2 : DATA_BLOB gd_cp850 = base64_decode_data_blob(gd_cp850_base64);
160 2 : DATA_BLOB gd_iso8859_1 = base64_decode_data_blob(gd_iso8859_1_base64);
161 2 : DATA_BLOB gd_utf16le = base64_decode_data_blob(gd_utf16le_base64);
162 2 : DATA_BLOB gd_output;
163 2 : DATA_BLOB gd_output2;
164 :
165 2 : talloc_steal(tctx, gd_utf8.data);
166 2 : talloc_steal(tctx, gd_cp850.data);
167 2 : talloc_steal(tctx, gd_iso8859_1.data);
168 2 : talloc_steal(tctx, gd_utf16le.data);
169 :
170 2 : iconv_handle = get_iconv_testing_handle(tctx, "ISO-8859-1", "CP850",
171 2 : lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
172 2 : torture_assert(tctx, iconv_handle, "getting iconv handle");
173 :
174 2 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
175 : CH_UTF8, CH_DOS,
176 : gd_utf8.data, gd_utf8.length,
177 : (void *)&gd_output.data, &gd_output.length),
178 : "conversion from UTF8 to (dos charset) ISO-8859-1");
179 2 : torture_assert_data_blob_equal(tctx, gd_output, gd_iso8859_1, "conversion from UTF8 to (dos charset) ISO-8859-1 incorrect");
180 :
181 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
182 : CH_UTF8, CH_DOS,
183 : gd_utf8.data, gd_utf8.length,
184 : (void *)gd_output.data, gd_output.length,
185 : &gd_output.length),
186 : "conversion from UTF8 to (dos charset) ISO-8859-1");
187 2 : torture_assert_data_blob_equal(tctx, gd_output, gd_iso8859_1, "conversion from UTF8 to (dos charset) ISO-8859-1 incorrect");
188 :
189 : /* Short output handling confirmation */
190 2 : gd_output.length = 1;
191 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
192 : CH_UTF8, CH_DOS,
193 : gd_utf8.data, gd_utf8.length,
194 : (void *)gd_output.data, gd_output.length,
195 : &gd_output.length) == false,
196 : "conversion from UTF8 to (dos charset) ISO-8859-1 should fail due to too short");
197 2 : torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to (dos charset) ISO-8859-1 should fail E2BIG");
198 2 : torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
199 2 : torture_assert_data_blob_equal(tctx, gd_output, data_blob_string_const("G"), "conversion from UTF8 to (dos charset) ISO-8859-1 incorrect");
200 :
201 : /* Short output handling confirmation */
202 2 : gd_output.length = 2;
203 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
204 : CH_UTF8, CH_DOS,
205 : gd_utf8.data, gd_utf8.length,
206 : (void *)gd_output.data, gd_output.length,
207 : &gd_output.length) == false,
208 : "conversion from UTF8 to (dos charset) ISO-8859-1 should fail due to too short");
209 2 : torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to (dos charset) ISO-8859-1 should fail E2BIG");
210 2 : torture_assert_int_equal(tctx, gd_output.length, 2, "Should only get 2 char of output");
211 :
212 : /* Short input handling confirmation */
213 2 : gd_output.length = gd_iso8859_1.length;
214 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
215 : CH_UTF8, CH_DOS,
216 : gd_utf8.data, 2,
217 : (void *)gd_output.data, gd_output.length,
218 : &gd_output.length) == false,
219 : "conversion from UTF8 to (dos charset) ISO-8859-1 should fail due to too short");
220 2 : torture_assert_errno_equal(tctx, EILSEQ, "conversion from short UTF8 to (dos charset) ISO-8859-1 should fail EINVAL");
221 1 : torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
222 :
223 : /* Short output handling confirmation */
224 1 : gd_output.length = 1;
225 1 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
226 : CH_UTF16LE, CH_UTF8,
227 : gd_utf16le.data, gd_utf16le.length,
228 : (void *)gd_output.data, gd_output.length,
229 : &gd_output.length) == false,
230 : "conversion from UTF16 to UTF8 should fail due to too short");
231 1 : torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16 to (utf8 charset) ISO-8859-1 should fail E2BIG");
232 1 : torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
233 1 : torture_assert_data_blob_equal(tctx, gd_output, data_blob_string_const("G"), "conversion from UTF16 to UTF8 incorrect");
234 :
235 : /* Short output handling confirmation */
236 1 : gd_output.length = 3;
237 1 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
238 : CH_UTF16LE, CH_UTF8,
239 : gd_utf16le.data, gd_utf16le.length,
240 : (void *)gd_output.data, gd_output.length,
241 : &gd_output.length) == false,
242 : "conversion from UTF16 to UTF8 should fail due to too short");
243 1 : torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16 to (utf8 charset) ISO-8859-1 should fail E2BIG");
244 1 : torture_assert_int_equal(tctx, gd_output.length, 3, "Should get 3 bytes output for UTF8");
245 :
246 : /* Short input handling confirmation */
247 1 : gd_output.length = gd_utf8.length;
248 1 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
249 : CH_UTF16LE, CH_UTF8,
250 : gd_utf16le.data, 3,
251 : (void *)gd_output.data, gd_output.length,
252 : &gd_output.length) == false,
253 : "conversion from UTF16 to UTF8 should fail due to too short");
254 1 : torture_assert_errno_equal(tctx, EINVAL, "conversion from short UTF16 to UTF8 should fail EINVAL");
255 1 : torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
256 :
257 1 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
258 : CH_UTF8, CH_UNIX,
259 : gd_utf8.data, gd_utf8.length,
260 : (void *)&gd_output.data, &gd_output.length),
261 : "conversion from UTF8 to (unix charset) CP850");
262 1 : torture_assert_data_blob_equal(tctx, gd_output, gd_cp850, "conversion from UTF8 to (unix charset) CP850 incorrect");
263 :
264 1 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
265 : CH_UTF8, CH_UTF8,
266 : gd_utf8.data, gd_utf8.length,
267 : (void *)&gd_output.data, &gd_output.length),
268 : "conversion from UTF8 to UTF8");
269 1 : torture_assert_data_blob_equal(tctx, gd_output, gd_utf8, "conversion from UTF8 to UTF8 incorrect");
270 :
271 1 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
272 : CH_UTF16LE, CH_DOS,
273 : gd_utf16le.data, gd_utf16le.length,
274 : (void *)&gd_output.data, &gd_output.length),
275 : "conversion from UTF16LE to (dos charset) ISO-8859-1");
276 1 : torture_assert_data_blob_equal(tctx, gd_output, gd_iso8859_1, "conversion from UTF16LE to (dos charset) ISO-8859-1 incorrect");
277 :
278 1 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
279 : CH_DOS, CH_UTF16LE,
280 : gd_output.data, gd_output.length,
281 : (void *)&gd_output2.data, &gd_output2.length),
282 : "round trip conversion from (dos charset) ISO-8859-1 back to UTF16LE");
283 1 : torture_assert_data_blob_equal(tctx, gd_output2, gd_utf16le, "round trip conversion from (dos charset) ISO-8859-1 back to UTF16LE");
284 :
285 1 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
286 : CH_UTF16LE, CH_UNIX,
287 : gd_utf16le.data, gd_utf16le.length,
288 : (void *)&gd_output.data, &gd_output.length),
289 : "conversion from UTF16LE to (unix charset) CP850");
290 1 : torture_assert_data_blob_equal(tctx, gd_output, gd_cp850, "conversion from UTF16LE to (unix charset) CP850 incorrect");
291 :
292 1 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
293 : CH_UTF16LE, CH_UTF8,
294 : gd_utf16le.data, gd_utf16le.length,
295 : (void *)&gd_output.data, &gd_output.length),
296 : "conversion from UTF16LE to UTF8");
297 1 : torture_assert_data_blob_equal(tctx, gd_output, gd_utf8, "conversion from UTF16LE to UTF8 incorrect");
298 :
299 1 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
300 : CH_DOS, CH_DOS,
301 : gd_iso8859_1.data, gd_iso8859_1.length,
302 : (void *)&gd_output.data, &gd_output.length),
303 : "conversion from (dos charset) ISO-8859-1 to (dos charset) ISO-8859-1");
304 1 : torture_assert_data_blob_equal(tctx, gd_output, gd_iso8859_1, "conversion from UTF16LE to (dos charset) ISO-8859-1 incorrect");
305 :
306 1 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
307 : CH_DOS, CH_UNIX,
308 : gd_iso8859_1.data, gd_iso8859_1.length,
309 : (void *)&gd_output.data, &gd_output.length),
310 : "conversion from (dos charset) ISO-8859-1 to (unix charset) CP850");
311 1 : torture_assert_data_blob_equal(tctx, gd_output, gd_cp850, "conversion from UTF16LE to (unix charset) CP850 incorrect");
312 :
313 1 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
314 : CH_DOS, CH_UTF8,
315 : gd_iso8859_1.data, gd_iso8859_1.length,
316 : (void *)&gd_output.data, &gd_output.length),
317 : "conversion from (dos charset) ISO-8859-1 to UTF8");
318 1 : torture_assert_data_blob_equal(tctx, gd_output, gd_utf8, "conversion from UTF16LE to UTF8 incorrect");
319 :
320 1 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
321 : CH_DOS, CH_UTF16LE,
322 : gd_iso8859_1.data, gd_iso8859_1.length,
323 : (void *)&gd_output.data, &gd_output.length),
324 : "conversion from (dos charset) ISO-8859-1 to UTF16LE");
325 1 : torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le, "conversion from (dos charset) ISO-8859-1 to UTF16LE");
326 1 : torture_assert_int_equal(tctx,
327 : strlen_m_ext_handle(iconv_handle,
328 : (const char *)gd_iso8859_1.data,
329 : CH_DOS, CH_UTF16LE),
330 : gd_output.length / 2,
331 : "checking strlen_m_ext of round trip conversion of UTF16 latin charset greek to UTF8 and back again");
332 :
333 1 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
334 : CH_DOS, CH_UTF8,
335 : gd_iso8859_1.data, gd_iso8859_1.length,
336 : (void *)&gd_output.data, &gd_output.length),
337 : "conversion from (dos charset) ISO-8859-1 to UTF8");
338 1 : torture_assert_data_blob_equal(tctx, gd_output, gd_utf8, "conversion from (dos charset) ISO-8859-1 to UTF8");
339 1 : torture_assert_int_equal(tctx,
340 : strlen_m_ext_handle(iconv_handle,
341 : (const char *)gd_iso8859_1.data,
342 : CH_DOS, CH_UTF8),
343 : gd_output.length,
344 : "checking strlen_m_ext of conversion from (dos charset) ISO-8859-1 to UTF8");
345 0 : return true;
346 : }
347 :
348 2 : static bool test_gd_minus_1_handle(struct torture_context *tctx)
349 : {
350 2 : struct smb_iconv_handle *iconv_handle;
351 2 : DATA_BLOB gd_utf8 = base64_decode_data_blob(gd_utf8_base64);
352 2 : DATA_BLOB gd_cp850 = base64_decode_data_blob(gd_cp850_base64);
353 2 : DATA_BLOB gd_utf16le = base64_decode_data_blob(gd_utf16le_base64);
354 2 : DATA_BLOB gd_output;
355 2 : DATA_BLOB gd_utf8_terminated;
356 2 : DATA_BLOB gd_cp850_terminated;
357 2 : DATA_BLOB gd_utf16le_terminated;
358 :
359 2 : talloc_steal(tctx, gd_utf8.data);
360 2 : talloc_steal(tctx, gd_cp850.data);
361 2 : talloc_steal(tctx, gd_utf16le.data);
362 :
363 2 : iconv_handle = get_iconv_testing_handle(tctx, "CP850", "CP850",
364 2 : lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
365 2 : torture_assert(tctx, iconv_handle, "getting iconv handle");
366 :
367 2 : gd_utf8_terminated = data_blob_talloc(tctx, NULL, gd_utf8.length + 1);
368 2 : memcpy(gd_utf8_terminated.data, gd_utf8.data, gd_utf8.length);
369 2 : gd_utf8_terminated.data[gd_utf8.length] = '\0';
370 :
371 2 : gd_cp850_terminated = data_blob_talloc(tctx, NULL, gd_cp850.length + 1);
372 2 : memcpy(gd_cp850_terminated.data, gd_cp850.data, gd_cp850.length);
373 2 : gd_cp850_terminated.data[gd_cp850.length] = '\0';
374 :
375 2 : gd_utf16le_terminated = data_blob_talloc(tctx, NULL, gd_utf16le.length + 2);
376 2 : memcpy(gd_utf16le_terminated.data, gd_utf16le.data, gd_utf16le.length);
377 2 : gd_utf16le_terminated.data[gd_utf16le.length] = '\0';
378 2 : gd_utf16le_terminated.data[gd_utf16le.length + 1] = '\0';
379 :
380 2 : gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
381 :
382 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
383 : CH_UTF8, CH_UTF16LE,
384 : gd_utf8_terminated.data, -1,
385 : (void *)gd_output.data, gd_output.length, &gd_output.length),
386 : "conversion from UTF8 to UTF16LE null terminated");
387 2 : torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated");
388 :
389 2 : gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
390 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
391 : CH_UTF8, CH_UTF16LE,
392 : gd_utf8_terminated.data, -1,
393 : (void *)gd_output.data, gd_utf16le.length, &gd_output.length) == false,
394 : "conversion from UTF8 to UTF16LE null terminated should fail");
395 2 : torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
396 2 : torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le, "conversion from UTF8 to UTF16LE null terminated");
397 :
398 2 : gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
399 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
400 : CH_UTF8, CH_UTF16LE,
401 : gd_utf8_terminated.data, -1,
402 : (void *)gd_output.data, gd_utf16le.length - 1, &gd_output.length) == false,
403 : "conversion from UTF8 to UTF16LE null terminated should fail");
404 2 : torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
405 :
406 2 : gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
407 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
408 : CH_UTF8, CH_UTF16LE,
409 : gd_utf8_terminated.data, -1,
410 : (void *)gd_output.data, gd_utf16le.length - 2, &gd_output.length) == false,
411 : "conversion from UTF8 to UTF16LE null terminated should fail");
412 2 : torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
413 :
414 2 : gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10);
415 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
416 : CH_UTF16LE, CH_UTF8,
417 : gd_utf16le_terminated.data, -1,
418 : (void *)gd_output.data, gd_output.length, &gd_output.length),
419 : "conversion from UTF16LE to UTF8 null terminated");
420 2 : torture_assert_data_blob_equal(tctx, gd_output, gd_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated");
421 :
422 2 : gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10);
423 :
424 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
425 : CH_UTF16LE, CH_UTF8,
426 : gd_utf16le_terminated.data, -1,
427 : (void *)gd_output.data, gd_utf8.length, &gd_output.length) == false,
428 : "conversion from UTF16LE to UTF8 null terminated should fail");
429 2 : torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
430 2 : torture_assert_data_blob_equal(tctx, gd_output, gd_utf8, "conversion from UTF16LE to UTF8 null terminated");
431 :
432 2 : gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10);
433 :
434 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
435 : CH_UTF16LE, CH_UTF8,
436 : gd_utf16le_terminated.data, -1,
437 : (void *)gd_output.data, gd_utf8.length - 1, &gd_output.length) == false,
438 : "conversion from UTF16LE to UTF8 null terminated should fail");
439 2 : torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
440 :
441 2 : gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10);
442 :
443 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
444 : CH_UTF16LE, CH_UTF8,
445 : gd_utf16le_terminated.data, -1,
446 : (void *)gd_output.data, gd_utf8.length - 2, &gd_output.length) == false,
447 : "conversion from UTF16LE to UTF8 null terminated should fail");
448 2 : torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
449 :
450 2 : gd_output = data_blob_talloc(tctx, NULL, gd_cp850.length + 10);
451 :
452 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
453 : CH_UTF16LE, CH_DOS,
454 : gd_utf16le_terminated.data, -1,
455 : (void *)gd_output.data, gd_output.length, &gd_output.length),
456 : "conversion from UTF16LE to CP850 (dos) null terminated");
457 2 : torture_assert_data_blob_equal(tctx, gd_output, gd_cp850_terminated, "conversion from UTF16LE to CP850 (dos) null terminated");
458 :
459 : /* Now null terminate the string early, the confirm we don't skip the NULL and convert any further */
460 2 : gd_utf8_terminated.data[3] = '\0';
461 2 : gd_utf8_terminated.length = 4; /* used for the comparison only */
462 :
463 2 : gd_cp850_terminated.data[2] = '\0';
464 2 : gd_cp850_terminated.length = 3; /* used for the comparison only */
465 :
466 2 : gd_utf16le_terminated.data[4] = '\0';
467 2 : gd_utf16le_terminated.data[5] = '\0';
468 2 : gd_utf16le_terminated.length = 6; /* used for the comparison only */
469 :
470 2 : gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
471 :
472 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
473 : CH_UTF8, CH_UTF16LE,
474 : gd_utf8_terminated.data, -1,
475 : (void *)gd_output.data, gd_output.length, &gd_output.length),
476 : "conversion from UTF8 to UTF16LE null terminated");
477 2 : torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated early");
478 :
479 2 : gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10);
480 :
481 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
482 : CH_UTF16LE, CH_UTF8,
483 : gd_utf16le_terminated.data, -1,
484 : (void *)gd_output.data, gd_output.length, &gd_output.length),
485 : "conversion from UTF16LE to UTF8 null terminated");
486 2 : torture_assert_data_blob_equal(tctx, gd_output, gd_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated early");
487 :
488 2 : gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
489 :
490 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
491 : CH_DOS, CH_UTF16LE,
492 : gd_cp850_terminated.data, -1,
493 : (void *)gd_output.data, gd_output.length, &gd_output.length),
494 : "conversion from CP850 to UTF16LE null terminated");
495 2 : torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated early");
496 :
497 2 : gd_output = data_blob_talloc(tctx, NULL, gd_cp850.length + 10);
498 :
499 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
500 : CH_UTF16LE, CH_DOS,
501 : gd_utf16le_terminated.data, -1,
502 : (void *)gd_output.data, gd_output.length, &gd_output.length),
503 : "conversion from UTF16LE to UTF8 null terminated");
504 2 : torture_assert_data_blob_equal(tctx, gd_output, gd_cp850_terminated, "conversion from UTF16LE to UTF8 null terminated early");
505 :
506 : /* Now null terminate the string particularly early, the confirm we don't skip the NULL and convert any further */
507 2 : gd_utf8_terminated.data[1] = '\0';
508 2 : gd_utf8_terminated.length = 2; /* used for the comparison only */
509 :
510 2 : gd_utf16le_terminated.data[2] = '\0';
511 2 : gd_utf16le_terminated.data[3] = '\0';
512 2 : gd_utf16le_terminated.length = 4; /* used for the comparison only */
513 :
514 2 : gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
515 :
516 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle, CH_UTF8, CH_UTF16LE,
517 : gd_utf8_terminated.data, -1,
518 : (void *)gd_output.data, gd_output.length, &gd_output.length),
519 : "conversion from UTF8 to UTF16LE null terminated");
520 2 : torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated very early");
521 :
522 2 : gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10);
523 :
524 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
525 : CH_UTF16LE, CH_UTF8,
526 : gd_utf16le_terminated.data, -1,
527 : (void *)gd_output.data, gd_output.length, &gd_output.length),
528 : "conversion from UTF16LE to UTF8 null terminated");
529 2 : torture_assert_data_blob_equal(tctx, gd_output, gd_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated very early");
530 :
531 0 : return true;
532 : }
533 :
534 2 : static bool test_gd_ascii_handle(struct torture_context *tctx)
535 : {
536 2 : struct smb_iconv_handle *iconv_handle;
537 2 : DATA_BLOB gd_utf8 = base64_decode_data_blob(gd_utf8_base64);
538 2 : DATA_BLOB gd_cp850 = base64_decode_data_blob(gd_cp850_base64);
539 2 : DATA_BLOB gd_iso8859_1 = base64_decode_data_blob(gd_iso8859_1_base64);
540 2 : DATA_BLOB gd_utf16le = base64_decode_data_blob(gd_utf16le_base64);
541 2 : DATA_BLOB gd_output;
542 :
543 2 : talloc_steal(tctx, gd_utf8.data);
544 2 : talloc_steal(tctx, gd_cp850.data);
545 2 : talloc_steal(tctx, gd_iso8859_1.data);
546 2 : talloc_steal(tctx, gd_utf16le.data);
547 :
548 2 : iconv_handle = get_iconv_testing_handle(tctx, "ASCII", "UTF8",
549 2 : lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
550 2 : torture_assert(tctx, iconv_handle, "getting iconv handle");
551 :
552 2 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
553 : CH_UTF8, CH_DOS,
554 : gd_utf8.data, gd_utf8.length,
555 : (void *)&gd_output.data, &gd_output.length) == false,
556 : "conversion from UTF8 to (dos charset) ASCII should fail");
557 :
558 2 : gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length);
559 :
560 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
561 : CH_UTF8, CH_DOS,
562 : gd_utf8.data, gd_utf8.length,
563 : (void *)gd_output.data, gd_output.length,
564 : &gd_output.length) == false,
565 : "conversion from UTF8 to (dos charset) ASCII should fail");
566 2 : torture_assert_errno_equal(tctx, EILSEQ, "conversion from UTF8 to (dos charset) ISO-8859-1 should fail E2BIG");
567 2 : torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
568 2 : torture_assert_data_blob_equal(tctx, gd_output, data_blob_string_const("G"), "partial conversion from UTF8 to (dos charset) ASCII incorrect");
569 :
570 : /* Short output handling confirmation */
571 2 : gd_output.length = 1;
572 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
573 : CH_UTF8, CH_DOS,
574 : gd_utf8.data, gd_utf8.length,
575 : (void *)gd_output.data, gd_output.length,
576 : &gd_output.length) == false,
577 : "conversion from UTF8 to (dos charset) ASCII should fail due to too short");
578 2 : torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to (dos charset) ASCII too short");
579 2 : torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
580 2 : torture_assert_data_blob_equal(tctx, gd_output, data_blob_string_const("G"), "conversion from UTF8 to (dos charset) ASCII incorrect");
581 :
582 : /* Short output handling confirmation */
583 2 : gd_output.length = 2;
584 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
585 : CH_UTF8, CH_DOS,
586 : gd_utf8.data, gd_utf8.length,
587 : (void *)gd_output.data, gd_output.length,
588 : &gd_output.length) == false,
589 : "conversion from UTF8 to (dos charset) ASCII should fail due to illegal sequence");
590 2 : torture_assert_errno_equal(tctx, EILSEQ, "conversion from UTF8 to (dos charset) ISO-8859-1 should fail EILSEQ");
591 2 : torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 2 char of output");
592 :
593 : /* Short input handling confirmation */
594 2 : gd_output.length = gd_utf8.length;
595 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
596 : CH_UTF8, CH_DOS,
597 : gd_utf8.data, 2,
598 : (void *)gd_output.data, gd_output.length,
599 : &gd_output.length) == false,
600 : "conversion from UTF8 to (dos charset) ASCII should fail due to too short");
601 2 : torture_assert_errno_equal(tctx, EILSEQ, "conversion from short UTF8 to (dos charset) ASCII should fail EILSEQ");
602 1 : torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
603 0 : return true;
604 : }
605 :
606 2 : static bool test_plato_english_iso8859_cp850_handle(struct torture_context *tctx)
607 : {
608 2 : struct smb_iconv_handle *iconv_handle;
609 2 : DATA_BLOB plato_english_utf8 = data_blob_string_const(plato_english_ascii);
610 2 : DATA_BLOB plato_english_cp850 = plato_english_utf8;
611 2 : DATA_BLOB plato_english_iso8859_1 = plato_english_utf8;
612 2 : DATA_BLOB plato_english_utf16le = base64_decode_data_blob(plato_english_utf16le_base64);
613 2 : DATA_BLOB plato_english_output;
614 2 : DATA_BLOB plato_english_output2;
615 :
616 2 : talloc_steal(tctx, plato_english_utf16le.data);
617 :
618 2 : iconv_handle = get_iconv_testing_handle(tctx, "ISO-8859-1", "CP850",
619 2 : lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
620 2 : torture_assert(tctx, iconv_handle, "getting iconv handle");
621 :
622 2 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
623 : CH_UTF8, CH_DOS,
624 : plato_english_utf8.data, plato_english_utf8.length,
625 : (void *)&plato_english_output.data, &plato_english_output.length),
626 : "conversion from UTF8 to (dos charset) ISO-8859-1");
627 2 : torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_iso8859_1, "conversion from UTF8 to (dos charset) ISO-8859-1 incorrect");
628 :
629 2 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
630 : CH_UTF8, CH_UNIX,
631 : plato_english_utf8.data, plato_english_utf8.length,
632 : (void *)&plato_english_output.data, &plato_english_output.length),
633 : "conversion from UTF8 to (unix charset) CP850");
634 2 : torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_cp850, "conversion from UTF8 to (unix charset) CP850 incorrect");
635 :
636 2 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
637 : CH_UTF8, CH_UTF8,
638 : plato_english_utf8.data, plato_english_utf8.length,
639 : (void *)&plato_english_output.data, &plato_english_output.length),
640 : "conversion from UTF8 to UTF8");
641 2 : torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF8 to UTF8 incorrect");
642 :
643 2 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
644 : CH_UTF16LE, CH_DOS,
645 : plato_english_utf16le.data, plato_english_utf16le.length,
646 : (void *)&plato_english_output.data, &plato_english_output.length),
647 : "conversion from UTF16LE to (dos charset) ISO-8859-1");
648 2 : torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_iso8859_1, "conversion from UTF16LE to (dos charset) ISO-8859-1 incorrect");
649 :
650 2 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
651 : CH_DOS, CH_UTF16LE,
652 : plato_english_output.data, plato_english_output.length,
653 : (void *)&plato_english_output2.data, &plato_english_output2.length),
654 : "round trip conversion from (dos charset) ISO-8859-1 back to UTF16LE");
655 2 : torture_assert_data_blob_equal(tctx, plato_english_output2, plato_english_utf16le, "round trip conversion from (dos charset) ISO-8859-1 back to UTF16LE");
656 :
657 2 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
658 : CH_UTF16LE, CH_UTF8,
659 : plato_english_utf16le.data, plato_english_utf16le.length,
660 : (void *)&plato_english_output.data, &plato_english_output.length),
661 : "conversion from UTF16LE to UTF8");
662 2 : torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF16LE to UTF8 incorrect");
663 :
664 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
665 : CH_UTF16LE, CH_UTF8,
666 : plato_english_utf16le.data, plato_english_utf16le.length,
667 : (void *)plato_english_output.data, plato_english_output.length,
668 : &plato_english_output.length),
669 : "conversion from UTF16LE to UTF8");
670 2 : torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF16LE to UTF8 incorrect");
671 :
672 2 : plato_english_output.length = 5;
673 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
674 : CH_UTF16LE, CH_UTF8,
675 : plato_english_utf16le.data, plato_english_utf16le.length,
676 : (void *)plato_english_output.data, plato_english_output.length,
677 : &plato_english_output.length) == false,
678 : "conversion from UTF16LE to UTF8 should fail due to short output");
679 2 : torture_assert_data_blob_equal(tctx, plato_english_output, data_blob_string_const("What "), "conversion from UTF16LE to UTF8 incorrect");
680 2 : torture_assert_int_equal(tctx, plato_english_output.length, 5, "short conversion failed");
681 :
682 2 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
683 : CH_UTF16LE, CH_UNIX,
684 : plato_english_utf16le.data, plato_english_utf16le.length,
685 : (void *)&plato_english_output.data, &plato_english_output.length),
686 : "conversion from UTF16LE to (unix charset) CP850");
687 2 : torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_cp850, "conversion from UTF16LE to (unix charset) CP850 incorrect");
688 :
689 2 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
690 : CH_UTF16LE, CH_UTF8,
691 : plato_english_utf16le.data, plato_english_utf16le.length,
692 : (void *)&plato_english_output.data, &plato_english_output.length),
693 : "conversion from UTF16LE to UTF8");
694 2 : torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF16LE to UTF8 incorrect");
695 :
696 2 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
697 : CH_DOS, CH_DOS,
698 : plato_english_iso8859_1.data, plato_english_iso8859_1.length,
699 : (void *)&plato_english_output.data, &plato_english_output.length),
700 : "conversion from (dos charset) ISO-8859-1 to (dos charset) ISO-8859-1");
701 2 : torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_iso8859_1, "conversion from UTF16LE to (dos charset) ISO-8859-1 incorrect");
702 :
703 2 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
704 : CH_DOS, CH_UNIX,
705 : plato_english_iso8859_1.data, plato_english_iso8859_1.length,
706 : (void *)&plato_english_output.data, &plato_english_output.length),
707 : "conversion from (dos charset) ISO-8859-1 to (unix charset) CP850");
708 2 : torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_cp850, "conversion from UTF16LE to (unix charset) CP850 incorrect");
709 :
710 2 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
711 : CH_DOS, CH_UTF8,
712 : plato_english_iso8859_1.data, plato_english_iso8859_1.length,
713 : (void *)&plato_english_output.data, &plato_english_output.length),
714 : "conversion from (dos charset) ISO-8859-1 to UTF8");
715 2 : torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF16LE to UTF8 incorrect");
716 :
717 2 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
718 : CH_DOS, CH_UTF16LE,
719 : plato_english_iso8859_1.data, plato_english_iso8859_1.length,
720 : (void *)&plato_english_output.data, &plato_english_output.length),
721 : "conversion from (dos charset) ISO-8859-1 to UTF16LE");
722 2 : torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf16le, "conversion from (dos charset) ISO-8859-1 to UTF16LE");
723 0 : return true;
724 : }
725 :
726 2 : static bool test_plato_english_minus_1_handle(struct torture_context *tctx)
727 : {
728 2 : struct smb_iconv_handle *iconv_handle;
729 2 : DATA_BLOB plato_english_utf8 = data_blob_string_const(plato_english_ascii);
730 2 : DATA_BLOB plato_english_utf16le = base64_decode_data_blob(plato_english_utf16le_base64);
731 2 : DATA_BLOB plato_english_output;
732 2 : DATA_BLOB plato_english_utf8_terminated;
733 2 : DATA_BLOB plato_english_utf16le_terminated;
734 :
735 2 : talloc_steal(tctx, plato_english_utf16le.data);
736 :
737 2 : iconv_handle = get_iconv_testing_handle(tctx, "ISO-8859-1", "CP850",
738 2 : lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
739 2 : torture_assert(tctx, iconv_handle, "getting iconv handle");
740 :
741 2 : plato_english_utf8_terminated = data_blob_talloc(tctx, NULL, plato_english_utf8.length + 1);
742 2 : memcpy(plato_english_utf8_terminated.data, plato_english_utf8.data, plato_english_utf8.length);
743 2 : plato_english_utf8_terminated.data[plato_english_utf8.length] = '\0';
744 :
745 2 : plato_english_utf16le_terminated = data_blob_talloc(tctx, NULL, plato_english_utf16le.length + 2);
746 2 : memcpy(plato_english_utf16le_terminated.data, plato_english_utf16le.data, plato_english_utf16le.length);
747 2 : plato_english_utf16le_terminated.data[plato_english_utf16le.length] = '\0';
748 2 : plato_english_utf16le_terminated.data[plato_english_utf16le.length + 1] = '\0';
749 :
750 2 : plato_english_output = data_blob_talloc(tctx, NULL, plato_english_utf16le.length + 10);
751 :
752 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
753 : CH_UTF8, CH_UTF16LE,
754 : plato_english_utf8_terminated.data, -1,
755 : (void *)plato_english_output.data, plato_english_output.length, &plato_english_output.length),
756 : "conversion from UTF8 to UTF16LE null terminated");
757 2 : torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated");
758 :
759 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
760 : CH_UTF8, CH_UTF16LE,
761 : plato_english_utf8_terminated.data, -1,
762 : (void *)plato_english_output.data, plato_english_utf16le.length, &plato_english_output.length) == false,
763 : "conversion from UTF8 to UTF16LE null terminated should fail");
764 2 : torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
765 2 : torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf16le, "conversion from UTF8 to UTF16LE null terminated");
766 :
767 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
768 : CH_UTF8, CH_UTF16LE,
769 : plato_english_utf8_terminated.data, -1,
770 : (void *)plato_english_output.data, plato_english_utf16le.length - 1, &plato_english_output.length) == false,
771 : "conversion from UTF8 to UTF16LE null terminated should fail");
772 2 : torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
773 :
774 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
775 : CH_UTF8, CH_UTF16LE,
776 : plato_english_utf8_terminated.data, -1,
777 : (void *)plato_english_output.data, plato_english_utf16le.length - 2, &plato_english_output.length) == false,
778 : "conversion from UTF8 to UTF16LE null terminated should fail");
779 2 : torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
780 :
781 2 : plato_english_output = data_blob_talloc(tctx, NULL, plato_english_utf8.length + 10);
782 :
783 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
784 : CH_UTF16LE, CH_UTF8,
785 : plato_english_utf16le_terminated.data, -1,
786 : (void *)plato_english_output.data, plato_english_output.length, &plato_english_output.length),
787 : "conversion from UTF16LE to UTF8 null terminated");
788 2 : torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated");
789 :
790 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
791 : CH_UTF16LE, CH_UTF8,
792 : plato_english_utf16le_terminated.data, -1,
793 : (void *)plato_english_output.data, plato_english_utf8.length, &plato_english_output.length) == false,
794 : "conversion from UTF16LE to UTF8 null terminated should fail");
795 2 : torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
796 2 : torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF16LE to UTF8 null terminated");
797 :
798 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
799 : CH_UTF16LE, CH_UTF8,
800 : plato_english_utf16le_terminated.data, -1,
801 : (void *)plato_english_output.data, plato_english_utf8.length - 1, &plato_english_output.length) == false,
802 : "conversion from UTF16LE to UTF8 null terminated should fail");
803 2 : torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
804 :
805 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
806 : CH_UTF16LE, CH_UTF8,
807 : plato_english_utf16le_terminated.data, -1,
808 : (void *)plato_english_output.data, plato_english_utf8.length - 2, &plato_english_output.length) == false,
809 : "conversion from UTF16LE to UTF8 null terminated should fail");
810 2 : torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
811 :
812 : /* Now null terminate the string early, the confirm we don't skip the NULL and convert any further */
813 2 : plato_english_utf8_terminated.data[3] = '\0';
814 2 : plato_english_utf8_terminated.length = 4; /* used for the comparison only */
815 :
816 2 : plato_english_utf16le_terminated.data[6] = '\0';
817 2 : plato_english_utf16le_terminated.data[7] = '\0';
818 2 : plato_english_utf16le_terminated.length = 8; /* used for the comparison only */
819 :
820 2 : plato_english_output = data_blob_talloc(tctx, NULL, plato_english_utf16le.length + 10);
821 :
822 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
823 : CH_UTF8, CH_UTF16LE,
824 : plato_english_utf8_terminated.data, -1,
825 : (void *)plato_english_output.data, plato_english_output.length, &plato_english_output.length),
826 : "conversion from UTF8 to UTF16LE null terminated");
827 2 : torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated early");
828 :
829 2 : plato_english_output = data_blob_talloc(tctx, NULL, plato_english_utf8.length + 10);
830 :
831 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
832 : CH_UTF16LE, CH_UTF8,
833 : plato_english_utf16le_terminated.data, -1,
834 : (void *)plato_english_output.data, plato_english_output.length, &plato_english_output.length),
835 : "conversion from UTF16LE to UTF8 null terminated");
836 2 : torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated early");
837 :
838 :
839 : /* Now null terminate the string particularly early, the confirm we don't skip the NULL and convert any further */
840 2 : plato_english_utf8_terminated.data[1] = '\0';
841 2 : plato_english_utf8_terminated.length = 2; /* used for the comparison only */
842 :
843 2 : plato_english_utf16le_terminated.data[2] = '\0';
844 2 : plato_english_utf16le_terminated.data[3] = '\0';
845 2 : plato_english_utf16le_terminated.length = 4; /* used for the comparison only */
846 :
847 2 : plato_english_output = data_blob_talloc(tctx, NULL, plato_english_utf16le.length + 10);
848 :
849 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle, CH_UTF8, CH_UTF16LE,
850 : plato_english_utf8_terminated.data, -1,
851 : (void *)plato_english_output.data, plato_english_output.length, &plato_english_output.length),
852 : "conversion from UTF8 to UTF16LE null terminated");
853 2 : torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated very early");
854 :
855 2 : plato_english_output = data_blob_talloc(tctx, NULL, plato_english_utf8.length + 10);
856 :
857 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
858 : CH_UTF16LE, CH_UTF8,
859 : plato_english_utf16le_terminated.data, -1,
860 : (void *)plato_english_output.data, plato_english_output.length, &plato_english_output.length),
861 : "conversion from UTF16LE to UTF8 null terminated");
862 2 : torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated very early");
863 :
864 0 : return true;
865 : }
866 :
867 2 : static bool test_plato_minus_1_handle(struct torture_context *tctx)
868 : {
869 2 : struct smb_iconv_handle *iconv_handle;
870 2 : DATA_BLOB plato_utf8 = base64_decode_data_blob(plato_utf8_base64);
871 2 : DATA_BLOB plato_utf16le = base64_decode_data_blob(plato_utf16le_base64);
872 2 : DATA_BLOB plato_output;
873 2 : DATA_BLOB plato_utf8_terminated;
874 2 : DATA_BLOB plato_utf16le_terminated;
875 :
876 2 : talloc_steal(tctx, plato_utf8.data);
877 2 : talloc_steal(tctx, plato_utf16le.data);
878 :
879 2 : iconv_handle = get_iconv_testing_handle(tctx, "ISO-8859-1", "CP850",
880 2 : lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
881 2 : torture_assert(tctx, iconv_handle, "getting iconv handle");
882 :
883 2 : plato_utf8_terminated = data_blob_talloc(tctx, NULL, plato_utf8.length + 1);
884 2 : memcpy(plato_utf8_terminated.data, plato_utf8.data, plato_utf8.length);
885 2 : plato_utf8_terminated.data[plato_utf8.length] = '\0';
886 :
887 2 : plato_utf16le_terminated = data_blob_talloc(tctx, NULL, plato_utf16le.length + 2);
888 2 : memcpy(plato_utf16le_terminated.data, plato_utf16le.data, plato_utf16le.length);
889 2 : plato_utf16le_terminated.data[plato_utf16le.length] = '\0';
890 2 : plato_utf16le_terminated.data[plato_utf16le.length + 1] = '\0';
891 :
892 2 : plato_output = data_blob_talloc(tctx, NULL, plato_utf16le.length + 10);
893 :
894 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
895 : CH_UTF8, CH_UTF16LE,
896 : plato_utf8_terminated.data, -1,
897 : (void *)plato_output.data, plato_output.length, &plato_output.length),
898 : "conversion from UTF8 to UTF16LE null terminated");
899 2 : torture_assert_data_blob_equal(tctx, plato_output, plato_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated");
900 :
901 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
902 : CH_UTF8, CH_UTF16LE,
903 : plato_utf8_terminated.data, -1,
904 : (void *)plato_output.data, plato_utf16le.length, &plato_output.length) == false,
905 : "conversion from UTF8 to UTF16LE null terminated should fail");
906 2 : torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
907 2 : torture_assert_data_blob_equal(tctx, plato_output, plato_utf16le, "conversion from UTF8 to UTF16LE null terminated");
908 :
909 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
910 : CH_UTF8, CH_UTF16LE,
911 : plato_utf8_terminated.data, -1,
912 : (void *)plato_output.data, plato_utf16le.length - 1, &plato_output.length) == false,
913 : "conversion from UTF8 to UTF16LE null terminated should fail");
914 2 : torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
915 :
916 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
917 : CH_UTF8, CH_UTF16LE,
918 : plato_utf8_terminated.data, -1,
919 : (void *)plato_output.data, plato_utf16le.length - 2, &plato_output.length) == false,
920 : "conversion from UTF8 to UTF16LE null terminated should fail");
921 2 : torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
922 :
923 2 : plato_output = data_blob_talloc(tctx, NULL, plato_utf8.length + 10);
924 :
925 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
926 : CH_UTF16LE, CH_UTF8,
927 : plato_utf16le_terminated.data, -1,
928 : (void *)plato_output.data, plato_output.length, &plato_output.length),
929 : "conversion from UTF16LE to UTF8 null terminated");
930 2 : torture_assert_data_blob_equal(tctx, plato_output, plato_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated");
931 :
932 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
933 : CH_UTF16LE, CH_UTF8,
934 : plato_utf16le_terminated.data, -1,
935 : (void *)plato_output.data, plato_utf8.length, &plato_output.length) == false,
936 : "conversion from UTF16LE to UTF8 null terminated should fail");
937 2 : torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
938 2 : torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF16LE to UTF8 null terminated");
939 :
940 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
941 : CH_UTF16LE, CH_UTF8,
942 : plato_utf16le_terminated.data, -1,
943 : (void *)plato_output.data, plato_utf8.length - 1, &plato_output.length) == false,
944 : "conversion from UTF16LE to UTF8 null terminated should fail");
945 2 : torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
946 :
947 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
948 : CH_UTF16LE, CH_UTF8,
949 : plato_utf16le_terminated.data, -1,
950 : (void *)plato_output.data, plato_utf8.length - 2, &plato_output.length) == false,
951 : "conversion from UTF16LE to UTF8 null terminated should fail");
952 2 : torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
953 :
954 : /* Now null terminate the string early, the confirm we don't skip the NULL and convert any further */
955 2 : plato_utf8_terminated.data[5] = '\0';
956 2 : plato_utf8_terminated.length = 6; /* used for the comparison only */
957 :
958 2 : plato_utf16le_terminated.data[4] = '\0';
959 2 : plato_utf16le_terminated.data[5] = '\0';
960 2 : plato_utf16le_terminated.length = 6; /* used for the comparison only */
961 :
962 2 : plato_output = data_blob_talloc(tctx, NULL, plato_utf16le.length + 10);
963 :
964 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
965 : CH_UTF8, CH_UTF16LE,
966 : plato_utf8_terminated.data, -1,
967 : (void *)plato_output.data, plato_output.length, &plato_output.length),
968 : "conversion from UTF8 to UTF16LE null terminated");
969 2 : torture_assert_data_blob_equal(tctx, plato_output, plato_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated early");
970 :
971 2 : plato_output = data_blob_talloc(tctx, NULL, plato_utf8.length + 10);
972 :
973 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
974 : CH_UTF16LE, CH_UTF8,
975 : plato_utf16le_terminated.data, -1,
976 : (void *)plato_output.data, plato_output.length, &plato_output.length),
977 : "conversion from UTF16LE to UTF8 null terminated");
978 2 : torture_assert_data_blob_equal(tctx, plato_output, plato_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated early");
979 :
980 0 : return true;
981 : }
982 :
983 2 : static bool test_plato_cp850_utf8_handle(struct torture_context *tctx)
984 : {
985 2 : struct smb_iconv_handle *iconv_handle;
986 2 : DATA_BLOB plato_utf8 = base64_decode_data_blob(plato_utf8_base64);
987 2 : DATA_BLOB plato_utf16le = base64_decode_data_blob(plato_utf16le_base64);
988 2 : DATA_BLOB plato_output;
989 2 : DATA_BLOB plato_output2;
990 :
991 2 : talloc_steal(tctx, plato_utf8.data);
992 2 : talloc_steal(tctx, plato_utf16le.data);
993 :
994 2 : iconv_handle = get_iconv_testing_handle(tctx, "CP850", "UTF8",
995 2 : lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
996 2 : torture_assert(tctx, iconv_handle, "creating iconv handle");
997 :
998 2 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
999 : CH_UTF8, CH_UTF16LE,
1000 : plato_utf8.data, plato_utf8.length,
1001 : (void *)&plato_output.data, &plato_output.length),
1002 : "conversion of UTF8 ancient greek to UTF16 failed");
1003 2 : torture_assert_data_blob_equal(tctx, plato_output, plato_utf16le, "conversion from UTF8 to UTF16LE incorrect");
1004 :
1005 2 : torture_assert_int_equal(tctx,
1006 : strlen_m_ext_handle(iconv_handle,
1007 : (const char *)plato_utf8.data,
1008 : CH_UTF8, CH_UTF16LE),
1009 : plato_output.length / 2,
1010 : "checking strlen_m_ext of conversion of UTF8 to UTF16LE");
1011 :
1012 2 : memset(plato_output.data, '\0', plato_output.length);
1013 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
1014 : CH_UTF8, CH_UTF16LE,
1015 : plato_utf8.data, plato_utf8.length,
1016 : (void *)plato_output.data, plato_output.length,
1017 : &plato_output.length),
1018 : "conversion of UTF8 ancient greek to UTF16 failed");
1019 2 : torture_assert_data_blob_equal(tctx, plato_output, plato_utf16le, "conversion from UTF8 to UTF16LE incorrect");
1020 :
1021 2 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1022 : CH_UTF16LE, CH_UTF8,
1023 : plato_output.data, plato_output.length,
1024 : (void *)&plato_output2.data, &plato_output2.length),
1025 : "conversion of UTF8 ancient greek to UTF16 failed");
1026 2 : torture_assert_data_blob_equal(tctx, plato_output2, plato_utf8, "conversion from UTF8 to UTF16LE incorrect");
1027 :
1028 2 : memset(plato_output2.data, '\0', plato_output2.length);
1029 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
1030 : CH_UTF16LE, CH_UTF8,
1031 : plato_output.data, plato_output.length,
1032 : (void *)plato_output2.data, plato_output2.length, &plato_output2.length),
1033 : "conversion of UTF8 ancient greek to UTF16 failed");
1034 2 : torture_assert_data_blob_equal(tctx, plato_output2, plato_utf8, "conversion from UTF8 to UTF16LE incorrect");
1035 :
1036 2 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1037 : CH_UTF8, CH_UTF8,
1038 : plato_utf8.data, plato_utf8.length,
1039 : (void *)&plato_output.data, &plato_output.length),
1040 : "conversion of UTF8 to UTF8");
1041 2 : torture_assert_data_blob_equal(tctx, plato_output, plato_utf8,
1042 : "conversion of UTF8 to UTF8");
1043 2 : torture_assert_int_equal(tctx,
1044 : strlen_m_ext_handle(iconv_handle,
1045 : (const char *)plato_utf8.data,
1046 : CH_UTF8, CH_UTF8),
1047 : plato_output.length,
1048 : "checking strlen_m_ext of conversion of UTF8 to UTF8");
1049 2 : memset(plato_output.data, '\0', plato_output.length);
1050 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
1051 : CH_UTF8, CH_UTF8,
1052 : plato_utf8.data, plato_utf8.length,
1053 : (void *)plato_output.data, plato_output.length,
1054 : &plato_output.length),
1055 : "conversion of UTF8 to UTF8");
1056 :
1057 2 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1058 : CH_UTF8, CH_DOS,
1059 : plato_utf8.data, plato_utf8.length,
1060 : (void *)&plato_output.data, &plato_output.length) == false,
1061 : "conversion of UTF8 ancient greek to DOS charset CP850 should fail");
1062 :
1063 2 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1064 : CH_UTF8, CH_UNIX,
1065 : plato_utf8.data, plato_utf8.length,
1066 : (void *)&plato_output.data, &plato_output.length),
1067 : "conversion of UTF16 ancient greek to unix charset UTF8 failed");
1068 2 : torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF8 to (unix charset) UTF8 incorrect");
1069 :
1070 2 : memset(plato_output.data, '\0', plato_output.length);
1071 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
1072 : CH_UTF8, CH_UNIX,
1073 : plato_utf8.data, plato_utf8.length,
1074 : (void *)plato_output.data, plato_output.length,
1075 : &plato_output.length),
1076 : "conversion of UTF16 ancient greek to unix charset UTF8 failed");
1077 2 : torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF8 to (unix charset) UTF8 incorrect");
1078 :
1079 2 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1080 : CH_UTF8, CH_UTF8,
1081 : plato_utf8.data, plato_utf8.length,
1082 : (void *)&plato_output.data, &plato_output.length),
1083 : "conversion of UTF16 ancient greek to unix charset UTF8 failed");
1084 2 : torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF8 to UTF8 incorrect");
1085 :
1086 2 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1087 : CH_UTF16LE, CH_DOS,
1088 : plato_utf16le.data, plato_utf16le.length,
1089 : (void *)&plato_output.data, &plato_output.length) == false,
1090 : "conversion of UTF16 ancient greek to DOS charset CP850 should fail");
1091 :
1092 : /* Allocate enough space, if it were possible do do the conversion */
1093 2 : plato_output = data_blob_talloc(tctx, NULL, plato_utf16le.length);
1094 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
1095 : CH_UTF16LE, CH_DOS,
1096 : plato_utf16le.data, plato_utf16le.length,
1097 : (void *)plato_output.data, plato_output.length,
1098 : &plato_output.length) == false,
1099 : "conversion of UTF16 ancient greek to DOS charset CP850 should fail");
1100 2 : torture_assert_errno_equal(tctx, EILSEQ, "conversion of UTF16 ancient greek to DOS charset CP850 should fail");
1101 :
1102 : /* Allocate only enough space for a partial conversion */
1103 2 : plato_output = data_blob_talloc(tctx, NULL, 9);
1104 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
1105 : CH_UTF16LE, CH_UTF8,
1106 : plato_utf16le.data, plato_utf16le.length,
1107 : (void *)plato_output.data, plato_output.length,
1108 : &plato_output.length) == false,
1109 : "conversion of UTF16 ancient greek to UTF8 should fail, not enough space");
1110 2 : torture_assert_errno_equal(tctx, E2BIG, "conversion of UTF16 ancient greek to UTF8 should fail, not enough space");
1111 2 : torture_assert_int_equal(tctx, plato_output.length, 8,
1112 : "conversion of UTF16 ancient greek to UTF8 should stop on multibyte boundary");
1113 :
1114 2 : plato_output = data_blob_talloc(tctx, NULL, 2);
1115 2 : torture_assert(tctx, convert_string_error_handle(iconv_handle,
1116 : CH_UTF16LE, CH_UTF8,
1117 : plato_utf16le.data, plato_utf16le.length,
1118 : (void *)plato_output.data, plato_output.length,
1119 : &plato_output.length) == false,
1120 : "conversion of UTF16 ancient greek to UTF8 should fail, not enough space");
1121 2 : torture_assert_errno_equal(tctx, E2BIG, "conversion of UTF16 ancient greek to UTF8 should fail, not enough space");
1122 2 : torture_assert_int_equal(tctx, plato_output.length, 0,
1123 : "conversion of UTF16 ancient greek to UTF8 should stop on multibyte boundary");
1124 :
1125 :
1126 2 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1127 : CH_UTF16LE, CH_UNIX,
1128 : plato_utf16le.data, plato_utf16le.length,
1129 : (void *)&plato_output.data, &plato_output.length),
1130 : "conversion of UTF16 ancient greek to unix charset UTF8 failed");
1131 2 : torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF16LE to (unix charset) UTF8 incorrect");
1132 2 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1133 : CH_UTF16LE, CH_UTF8,
1134 : plato_utf16le.data, plato_utf16le.length,
1135 : (void *)&plato_output.data, &plato_output.length),
1136 : "conversion of UTF16 ancient greek to UTF8 failed");
1137 2 : torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF16LE to UTF8 incorrect");
1138 2 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1139 : CH_UTF16LE, CH_UTF8,
1140 : plato_utf16le.data, plato_utf16le.length,
1141 : (void *)&plato_output.data, &plato_output.length),
1142 : "conversion of UTF16 ancient greek to UTF8 failed");
1143 2 : torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF16LE to UTF8 incorrect");
1144 :
1145 2 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1146 : CH_UTF8, CH_UTF16LE,
1147 : plato_output.data, plato_output.length,
1148 : (void *)&plato_output2.data, &plato_output2.length),
1149 : "round trip conversion of UTF16 ancient greek to UTF8 and back again failed");
1150 2 : torture_assert_data_blob_equal(tctx, plato_output2, plato_utf16le,
1151 : "round trip conversion of UTF16 ancient greek to UTF8 and back again failed");
1152 2 : torture_assert_int_equal(tctx,
1153 : strlen_m_ext_handle(iconv_handle,
1154 : (const char *)plato_output.data,
1155 : CH_UTF8, CH_UTF16LE),
1156 : plato_output2.length / 2,
1157 : "checking strlen_m_ext of round trip conversion of UTF16 latin charset greek to UTF8 and back again");
1158 :
1159 2 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1160 : CH_UTF8, CH_UTF8,
1161 : plato_output.data, plato_output.length,
1162 : (void *)&plato_output2.data, &plato_output2.length),
1163 : "conversion of UTF8 to UTF8");
1164 2 : torture_assert_data_blob_equal(tctx, plato_output2, plato_utf8,
1165 : "conversion of UTF8 to UTF8");
1166 2 : torture_assert_int_equal(tctx,
1167 : strlen_m_ext_handle(iconv_handle,
1168 : (const char *)plato_output.data,
1169 : CH_UTF8, CH_UTF8),
1170 : plato_output2.length,
1171 : "checking strlen_m_ext of conversion of UTF8 to UTF8");
1172 0 : return true;
1173 : }
1174 :
1175 2 : static bool test_plato_latin_cp850_utf8_handle(struct torture_context *tctx)
1176 : {
1177 2 : struct smb_iconv_handle *iconv_handle;
1178 2 : DATA_BLOB plato_latin_utf8 = base64_decode_data_blob(plato_latin_utf8_base64);
1179 2 : DATA_BLOB plato_latin_utf16le = base64_decode_data_blob(plato_latin_utf16le_base64);
1180 2 : DATA_BLOB plato_latin_output;
1181 2 : DATA_BLOB plato_latin_output2;
1182 :
1183 2 : talloc_steal(tctx, plato_latin_utf8.data);
1184 2 : talloc_steal(tctx, plato_latin_utf16le.data);
1185 :
1186 2 : iconv_handle = get_iconv_testing_handle(tctx, "CP850", "UTF8",
1187 2 : lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
1188 2 : torture_assert(tctx, iconv_handle, "creating iconv handle");
1189 :
1190 2 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1191 : CH_UTF8, CH_DOS,
1192 : plato_latin_utf8.data, plato_latin_utf8.length,
1193 : (void *)&plato_latin_output.data, &plato_latin_output.length) == false,
1194 : "conversion of UTF8 latin charset greek to DOS charset CP850 should fail");
1195 :
1196 2 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1197 : CH_UTF8, CH_UNIX,
1198 : plato_latin_utf8.data, plato_latin_utf8.length,
1199 : (void *)&plato_latin_output.data, &plato_latin_output.length),
1200 : "conversion of UTF16 latin charset greek to unix charset UTF8 failed");
1201 2 : torture_assert_data_blob_equal(tctx, plato_latin_output, plato_latin_utf8, "conversion from UTF8 to (unix charset) UTF8 incorrect");
1202 :
1203 2 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1204 : CH_UTF8, CH_UTF8,
1205 : plato_latin_utf8.data, plato_latin_utf8.length,
1206 : (void *)&plato_latin_output.data, &plato_latin_output.length),
1207 : "conversion of UTF16 latin charset greek to unix charset UTF8 failed");
1208 2 : torture_assert_data_blob_equal(tctx, plato_latin_output, plato_latin_utf8, "conversion from UTF8 to UTF8 incorrect");
1209 :
1210 2 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1211 : CH_UTF16LE, CH_DOS,
1212 : plato_latin_utf16le.data, plato_latin_utf16le.length,
1213 : (void *)&plato_latin_output.data, &plato_latin_output.length) == false,
1214 : "conversion of UTF16 latin charset greek to DOS charset CP850 should fail");
1215 :
1216 2 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1217 : CH_UTF16LE, CH_UNIX,
1218 : plato_latin_utf16le.data, plato_latin_utf16le.length,
1219 : (void *)&plato_latin_output.data, &plato_latin_output.length),
1220 : "conversion of UTF16 latin charset greek to unix charset UTF8 failed");
1221 2 : torture_assert_data_blob_equal(tctx, plato_latin_output, plato_latin_utf8, "conversion from UTF16LE to (unix charset) CP850 incorrect");
1222 :
1223 2 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1224 : CH_UTF16LE, CH_UTF8,
1225 : plato_latin_utf16le.data, plato_latin_utf16le.length,
1226 : (void *)&plato_latin_output.data, &plato_latin_output.length),
1227 : "conversion of UTF16 latin charset greek to UTF8 failed");
1228 2 : torture_assert_data_blob_equal(tctx, plato_latin_output, plato_latin_utf8, "conversion from UTF16LE to UTF8 incorrect");
1229 :
1230 2 : torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1231 : CH_UTF8, CH_UTF16LE,
1232 : plato_latin_output.data, plato_latin_output.length,
1233 : (void *)&plato_latin_output2.data, &plato_latin_output2.length),
1234 : "round trip conversion of UTF16 latin charset greek to UTF8 and back again failed");
1235 2 : torture_assert_data_blob_equal(tctx, plato_latin_output2, plato_latin_utf16le,
1236 : "round trip conversion of UTF16 latin charset greek to UTF8 and back again failed");
1237 2 : torture_assert_int_equal(tctx,
1238 : strlen_m_ext_handle(iconv_handle,
1239 : (const char *)plato_latin_output.data,
1240 : CH_UTF8, CH_UTF16LE),
1241 : plato_latin_output2.length / 2,
1242 : "checking strlen_m_ext of round trip conversion of UTF16 latin charset greek to UTF8 and back again");
1243 0 : return true;
1244 : }
1245 :
1246 2 : static bool test_utf8_nfc_to_nfd_overflow(struct torture_context *tctx)
1247 : {
1248 2 : smb_iconv_t ic;
1249 2 : DATA_BLOB utf8_nfc_blob;
1250 2 : DATA_BLOB utf8_nfd_blob;
1251 2 : DATA_BLOB src_blob;
1252 2 : DATA_BLOB blob;
1253 2 : size_t nconv;
1254 2 : const char *src = NULL;
1255 2 : char *dst = NULL;
1256 2 : size_t dst_left;
1257 2 : size_t srclen;
1258 2 : bool ret = true;
1259 :
1260 2 : ic = smb_iconv_open("UTF8-NFD", "UTF8-NFC");
1261 2 : torture_assert_goto(tctx, ic != (smb_iconv_t)-1, ret, done,
1262 : "creating iconv handle\n");
1263 :
1264 2 : utf8_nfc_blob = base64_decode_data_blob_talloc(tctx, utf8_nfc_base64);
1265 2 : torture_assert_not_null_goto(tctx, utf8_nfc_blob.data, ret, done,
1266 : "OOM\n");
1267 :
1268 2 : utf8_nfd_blob = base64_decode_data_blob_talloc(tctx, utf8_nfd_base64);
1269 2 : torture_assert_not_null_goto(tctx, utf8_nfd_blob.data, ret, done,
1270 : "OOM\n");
1271 :
1272 2 : blob = data_blob_talloc_zero(tctx, 255);
1273 2 : torture_assert_not_null_goto(tctx, blob.data, ret, done, "OOM\n");
1274 :
1275 : /*
1276 : * Unfortunately the current implementation that performs the conversion
1277 : * (using libicu) returns EINVAL if the result buffer is too small, not
1278 : * E2BIG like iconv().
1279 : */
1280 :
1281 2 : src = "foo";
1282 2 : srclen = 3;
1283 2 : dst = (char *)blob.data;
1284 2 : dst_left = 0;
1285 2 : nconv = smb_iconv(ic,
1286 : &src,
1287 : &srclen,
1288 : &dst,
1289 : &dst_left);
1290 2 : torture_assert_int_equal_goto(tctx, nconv, -1, ret, done,
1291 : "smb_iconv failed\n");
1292 2 : torture_assert_errno_equal_goto(tctx, EINVAL, ret, done,
1293 : "Wrong errno\n");
1294 :
1295 2 : src = "foo";
1296 2 : srclen = 3;
1297 2 : dst = (char *)blob.data;
1298 2 : dst_left = 1;
1299 2 : nconv = smb_iconv(ic,
1300 : &src,
1301 : &srclen,
1302 : &dst,
1303 : &dst_left);
1304 2 : torture_assert_int_equal_goto(tctx, nconv, -1, ret, done,
1305 : "smb_iconv failed\n");
1306 2 : torture_assert_errno_equal_goto(tctx, EINVAL, ret, done,
1307 : "Wrong errno\n");
1308 :
1309 2 : src = "foo";
1310 2 : srclen = 3;
1311 2 : dst = (char *)blob.data;
1312 2 : dst_left = 2;
1313 2 : nconv = smb_iconv(ic,
1314 : &src,
1315 : &srclen,
1316 : &dst,
1317 : &dst_left);
1318 2 : torture_assert_int_equal_goto(tctx, nconv, -1, ret, done,
1319 : "smb_iconv failed\n");
1320 2 : torture_assert_errno_equal_goto(tctx, EINVAL, ret, done,
1321 : "Wrong errno\n");
1322 :
1323 2 : src_blob = data_blob_const("foo", 3);
1324 2 : src = (const char *)src_blob.data;
1325 2 : srclen = src_blob.length;
1326 2 : dst = (char *)blob.data;
1327 2 : dst_left = 3;
1328 2 : nconv = smb_iconv(ic,
1329 : &src,
1330 : &srclen,
1331 : &dst,
1332 : &dst_left);
1333 2 : torture_assert_int_equal_goto(tctx, nconv, 3, ret, done,
1334 : "smb_iconv failed\n");
1335 :
1336 2 : blob.length = nconv;
1337 2 : torture_assert_data_blob_equal(tctx,
1338 : src_blob,
1339 : blob,
1340 : "Conversion failed\n");
1341 :
1342 2 : src_blob = data_blob_const("foo", 4);
1343 2 : src = (const char *)src_blob.data;
1344 2 : srclen = src_blob.length;
1345 2 : dst = (char *)blob.data;
1346 2 : dst_left = 4;
1347 2 : nconv = smb_iconv(ic,
1348 : &src,
1349 : &srclen,
1350 : &dst,
1351 : &dst_left);
1352 2 : torture_assert_int_equal_goto(tctx, nconv, 4, ret, done,
1353 : "smb_iconv failed\n");
1354 :
1355 2 : blob.length = nconv;
1356 2 : torture_assert_data_blob_equal(tctx,
1357 : src_blob,
1358 : blob,
1359 : "Conversion failed\n");
1360 :
1361 0 : done:
1362 0 : return ret;
1363 : }
1364 :
1365 2 : static bool test_utf8_nfc_to_nfd(struct torture_context *tctx)
1366 : {
1367 2 : smb_iconv_t ic;
1368 2 : DATA_BLOB utf8_nfc_blob;
1369 2 : DATA_BLOB utf8_nfd_blob;
1370 2 : DATA_BLOB blob;
1371 2 : size_t nconv;
1372 2 : const char *src = NULL;
1373 2 : char *dst = NULL;
1374 2 : size_t dst_left;
1375 2 : size_t srclen;
1376 2 : bool ret = true;
1377 :
1378 2 : ic = smb_iconv_open("UTF8-NFD", "UTF8-NFC");
1379 2 : torture_assert_goto(tctx, ic != (smb_iconv_t)-1, ret, done,
1380 : "creating iconv handle\n");
1381 :
1382 2 : utf8_nfc_blob = base64_decode_data_blob_talloc(tctx, utf8_nfc_base64);
1383 2 : torture_assert_not_null_goto(tctx, utf8_nfc_blob.data, ret, done,
1384 : "OOM\n");
1385 :
1386 2 : utf8_nfd_blob = base64_decode_data_blob_talloc(tctx, utf8_nfd_base64);
1387 2 : torture_assert_not_null_goto(tctx, utf8_nfd_blob.data, ret, done,
1388 : "OOM\n");
1389 :
1390 2 : blob = data_blob_talloc_zero(tctx, 255);
1391 2 : torture_assert_not_null_goto(tctx, blob.data, ret, done, "OOM\n");
1392 :
1393 2 : dst = (char *)blob.data;
1394 2 : dst_left = blob.length;
1395 2 : src = (const char *)utf8_nfc_blob.data;
1396 2 : srclen = strlen(src);
1397 :
1398 2 : nconv = smb_iconv(ic,
1399 : &src,
1400 : &srclen,
1401 : &dst,
1402 : &dst_left);
1403 2 : torture_assert_goto(tctx, nconv != (size_t)-1, ret, done,
1404 : "smb_iconv failed\n");
1405 :
1406 2 : blob.length = nconv + 1; /* +1 for the trailing zero */
1407 2 : torture_assert_data_blob_equal(tctx,
1408 : blob,
1409 : utf8_nfd_blob,
1410 : "Conversion failed\n");
1411 :
1412 0 : done:
1413 0 : return ret;
1414 : }
1415 :
1416 2 : static bool test_utf8_nfd_to_nfc(struct torture_context *tctx)
1417 : {
1418 2 : smb_iconv_t ic;
1419 2 : DATA_BLOB utf8_nfc_blob;
1420 2 : DATA_BLOB utf8_nfd_blob;
1421 2 : DATA_BLOB blob;
1422 2 : size_t nconv;
1423 2 : const char *src = NULL;
1424 2 : char *dst = NULL;
1425 2 : size_t dst_left;
1426 2 : size_t srclen;
1427 2 : bool ret = true;
1428 :
1429 2 : ic = smb_iconv_open("UTF8-NFC", "UTF8-NFD");
1430 2 : torture_assert_goto(tctx, ic != (smb_iconv_t)-1, ret, done,
1431 : "creating iconv handle\n");
1432 :
1433 2 : utf8_nfc_blob = base64_decode_data_blob_talloc(tctx, utf8_nfc_base64);
1434 2 : torture_assert_not_null_goto(tctx, utf8_nfc_blob.data, ret, done,
1435 : "OOM\n");
1436 :
1437 2 : utf8_nfd_blob = base64_decode_data_blob_talloc(tctx, utf8_nfd_base64);
1438 2 : torture_assert_not_null_goto(tctx, utf8_nfd_blob.data, ret, done,
1439 : "OOM\n");
1440 :
1441 2 : blob = data_blob_talloc_zero(tctx, 255);
1442 2 : torture_assert_not_null_goto(tctx, blob.data, ret, done, "OOM\n");
1443 :
1444 2 : dst = (char *)blob.data;
1445 2 : dst_left = blob.length;
1446 2 : src = (const char *)utf8_nfd_blob.data;
1447 2 : srclen = strlen(src);
1448 :
1449 2 : nconv = smb_iconv(ic,
1450 : &src,
1451 : &srclen,
1452 : &dst,
1453 : &dst_left);
1454 2 : torture_assert_goto(tctx, nconv != (size_t)-1, ret, done,
1455 : "smb_iconv failed\n");
1456 :
1457 2 : blob.length = nconv + 1; /* +1 for the trailing zero */
1458 2 : torture_assert_data_blob_equal(tctx,
1459 : blob,
1460 : utf8_nfc_blob,
1461 : "Conversion failed\n");
1462 :
1463 0 : done:
1464 0 : return ret;
1465 : }
1466 :
1467 2 : static bool test_gd_case_utf8_handle(struct torture_context *tctx)
1468 : {
1469 2 : struct smb_iconv_handle *iconv_handle;
1470 2 : DATA_BLOB gd_utf8 = base64_decode_data_blob(gd_utf8_base64);
1471 2 : DATA_BLOB gd_utf8_upper = base64_decode_data_blob(gd_utf8_upper_base64);
1472 2 : DATA_BLOB gd_utf8_lower = base64_decode_data_blob(gd_utf8_lower_base64);
1473 2 : char *gd_lower, *gd_upper;
1474 2 : talloc_steal(tctx, gd_utf8.data);
1475 :
1476 2 : iconv_handle = get_iconv_testing_handle(tctx, "ASCII", "UTF8",
1477 2 : lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
1478 2 : torture_assert(tctx, iconv_handle, "getting utf8 iconv handle");
1479 :
1480 2 : torture_assert(tctx,
1481 : strhasupper_handle(iconv_handle, (const char *)gd_utf8.data),
1482 : "GD's name has an upper case character");
1483 2 : torture_assert(tctx,
1484 : strhaslower_handle(iconv_handle, (const char *)gd_utf8.data),
1485 : "GD's name has an lower case character");
1486 2 : gd_lower = strlower_talloc_handle(iconv_handle, tctx, (const char *)gd_utf8.data);
1487 2 : torture_assert(tctx, gd_lower, "failed to convert GD's name into lower case");
1488 2 : torture_assert_data_blob_equal(tctx, data_blob_string_const(gd_lower), gd_utf8_lower,
1489 : "convert GD's name into lower case");
1490 2 : gd_upper = strupper_talloc_n_handle(iconv_handle, tctx, (const char *)gd_utf8.data, gd_utf8.length);
1491 2 : torture_assert(tctx, gd_lower, "failed to convert GD's name into upper case");
1492 2 : torture_assert_data_blob_equal(tctx, data_blob_string_const(gd_upper), gd_utf8_upper,
1493 : "convert GD's name into upper case");
1494 :
1495 2 : torture_assert(tctx,
1496 : strhasupper_handle(iconv_handle, gd_upper),
1497 : "upper case name has an upper case character");
1498 2 : torture_assert(tctx,
1499 : strhaslower_handle(iconv_handle, gd_lower),
1500 : "lower case name has an lower case character");
1501 2 : torture_assert(tctx,
1502 : strhasupper_handle(iconv_handle, gd_lower) == false,
1503 : "lower case name has no upper case character");
1504 2 : torture_assert(tctx,
1505 : strhaslower_handle(iconv_handle, gd_upper) == false,
1506 : "upper case name has no lower case character");
1507 :
1508 2 : torture_assert(tctx, strcasecmp_m_handle(iconv_handle, (const char *)gd_utf8.data,
1509 : gd_upper) == 0,
1510 : "case insensitive comparison orig/upper");
1511 2 : torture_assert(tctx, strcasecmp_m_handle(iconv_handle, (const char *)gd_utf8.data,
1512 : gd_lower) == 0,
1513 : "case insensitive comparison orig/lower");
1514 2 : torture_assert(tctx, strcasecmp_m_handle(iconv_handle, gd_upper,
1515 : gd_lower) == 0,
1516 : "case insensitive comparison upper/lower");
1517 :
1518 : /* This string isn't different in length upper/lower */
1519 2 : torture_assert(tctx, strncasecmp_m_handle(iconv_handle, (const char *)gd_utf8.data,
1520 : gd_upper, gd_utf8.length) == 0,
1521 : "case insensitive comparison orig/upper");
1522 2 : torture_assert(tctx, strncasecmp_m_handle(iconv_handle, (const char *)gd_utf8.data,
1523 : gd_lower, gd_utf8.length) == 0,
1524 : "case insensitive comparison orig/lower");
1525 2 : torture_assert(tctx, strncasecmp_m_handle(iconv_handle, gd_upper,
1526 : gd_lower, gd_utf8.length) == 0,
1527 : "case insensitive comparison upper/lower");
1528 :
1529 2 : data_blob_free(&gd_utf8);
1530 2 : data_blob_free(&gd_utf8_upper);
1531 2 : data_blob_free(&gd_utf8_lower);
1532 :
1533 2 : return true;
1534 : }
1535 :
1536 2 : static bool test_gd_case_cp850_handle(struct torture_context *tctx)
1537 : {
1538 2 : struct smb_iconv_handle *iconv_handle;
1539 2 : DATA_BLOB gd_cp850 = base64_decode_data_blob(gd_cp850_base64);
1540 2 : DATA_BLOB gd_cp850_upper = base64_decode_data_blob(gd_cp850_upper_base64);
1541 2 : DATA_BLOB gd_cp850_lower = base64_decode_data_blob(gd_cp850_lower_base64);
1542 2 : char *gd_lower, *gd_upper;
1543 2 : talloc_steal(tctx, gd_cp850.data);
1544 :
1545 2 : iconv_handle = get_iconv_testing_handle(tctx, "ASCII", "CP850",
1546 2 : lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
1547 2 : torture_assert(tctx, iconv_handle, "getting cp850 iconv handle");
1548 :
1549 2 : torture_assert(tctx,
1550 : strhasupper_handle(iconv_handle, (const char *)gd_cp850.data),
1551 : "GD's name has an upper case character");
1552 2 : torture_assert(tctx,
1553 : strhaslower_handle(iconv_handle, (const char *)gd_cp850.data),
1554 : "GD's name has an lower case character");
1555 2 : gd_lower = strlower_talloc_handle(iconv_handle, tctx, (const char *)gd_cp850.data);
1556 2 : torture_assert(tctx, gd_lower, "failed to convert GD's name into lower case");
1557 2 : torture_assert_data_blob_equal(tctx, data_blob_string_const(gd_lower), gd_cp850_lower,
1558 : "convert GD's name into lower case");
1559 2 : gd_upper = strupper_talloc_n_handle(iconv_handle, tctx, (const char *)gd_cp850.data, gd_cp850.length);
1560 2 : torture_assert(tctx, gd_lower, "failed to convert GD's name into upper case");
1561 2 : torture_assert_data_blob_equal(tctx, data_blob_string_const(gd_upper), gd_cp850_upper,
1562 : "convert GD's name into upper case");
1563 :
1564 2 : torture_assert(tctx,
1565 : strhasupper_handle(iconv_handle, gd_upper),
1566 : "upper case name has an upper case character");
1567 2 : torture_assert(tctx,
1568 : strhaslower_handle(iconv_handle, gd_lower),
1569 : "lower case name has an lower case character");
1570 2 : torture_assert(tctx,
1571 : strhasupper_handle(iconv_handle, gd_lower) == false,
1572 : "lower case name has no upper case character");
1573 2 : torture_assert(tctx,
1574 : strhaslower_handle(iconv_handle, gd_upper) == false,
1575 : "upper case name has no lower case character");
1576 :
1577 2 : torture_assert(tctx, strcasecmp_m_handle(iconv_handle, (const char *)gd_cp850.data,
1578 : gd_upper) == 0,
1579 : "case insensitive comparison orig/upper");
1580 2 : torture_assert(tctx, strcasecmp_m_handle(iconv_handle, (const char *)gd_cp850.data,
1581 : gd_lower) == 0,
1582 : "case insensitive comparison orig/lower");
1583 2 : torture_assert(tctx, strcasecmp_m_handle(iconv_handle, gd_upper,
1584 : gd_lower) == 0,
1585 : "case insensitive comparison upper/lower");
1586 :
1587 : /* This string isn't different in length upper/lower */
1588 2 : torture_assert(tctx, strncasecmp_m_handle(iconv_handle, (const char *)gd_cp850.data,
1589 : gd_upper, gd_cp850.length) == 0,
1590 : "case insensitive comparison orig/upper");
1591 2 : torture_assert(tctx, strncasecmp_m_handle(iconv_handle, (const char *)gd_cp850.data,
1592 : gd_lower, gd_cp850.length) == 0,
1593 : "case insensitive comparison orig/lower");
1594 2 : torture_assert(tctx, strncasecmp_m_handle(iconv_handle, gd_upper,
1595 : gd_lower, gd_cp850.length) == 0,
1596 : "case insensitive comparison upper/lower");
1597 :
1598 2 : data_blob_free(&gd_cp850);
1599 2 : data_blob_free(&gd_cp850_upper);
1600 2 : data_blob_free(&gd_cp850_lower);
1601 :
1602 2 : return true;
1603 : }
1604 :
1605 2 : static bool test_plato_case_utf8_handle(struct torture_context *tctx)
1606 : {
1607 2 : struct smb_iconv_handle *iconv_handle;
1608 2 : DATA_BLOB plato_utf8 = base64_decode_data_blob(plato_utf8_base64);
1609 2 : char *plato_lower, *plato_upper;
1610 2 : talloc_steal(tctx, plato_utf8.data);
1611 :
1612 2 : iconv_handle = get_iconv_testing_handle(tctx, "ASCII", "UTF8",
1613 2 : lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
1614 2 : torture_assert(tctx, iconv_handle, "getting utf8 iconv handle");
1615 :
1616 2 : torture_assert(tctx,
1617 : strhasupper_handle(iconv_handle, (const char *)plato_utf8.data),
1618 : "PLATO's apology has an upper case character");
1619 2 : torture_assert(tctx,
1620 : strhaslower_handle(iconv_handle, (const char *)plato_utf8.data),
1621 : "PLATO's apology has an lower case character");
1622 2 : plato_lower = strlower_talloc_handle(iconv_handle, tctx, (const char *)plato_utf8.data);
1623 2 : torture_assert(tctx, plato_lower, "failed to convert PLATO's apology into lower case");
1624 2 : plato_upper = strupper_talloc_n_handle(iconv_handle, tctx, (const char *)plato_utf8.data, plato_utf8.length);
1625 2 : torture_assert(tctx, plato_lower, "failed to convert PLATO's apology into upper case");
1626 :
1627 2 : torture_assert(tctx,
1628 : strhasupper_handle(iconv_handle, plato_upper),
1629 : "upper case string has an upper case character");
1630 2 : torture_assert(tctx,
1631 : strhaslower_handle(iconv_handle, plato_lower),
1632 : "lower case string has an lower case character");
1633 2 : torture_assert(tctx,
1634 : strhasupper_handle(iconv_handle, plato_lower) == false,
1635 : "lower case string has no upper case character");
1636 2 : torture_assert(tctx,
1637 : strhaslower_handle(iconv_handle, plato_upper) == false,
1638 : "upper case string has no lower case character");
1639 :
1640 2 : torture_assert(tctx, strcasecmp_m_handle(iconv_handle, (const char *)plato_utf8.data,
1641 : plato_upper) == 0,
1642 : "case insensitive comparison orig/upper");
1643 2 : torture_assert(tctx, strcasecmp_m_handle(iconv_handle, (const char *)plato_utf8.data,
1644 : plato_lower) == 0,
1645 : "case insensitive comparison orig/lower");
1646 2 : torture_assert(tctx, strcasecmp_m_handle(iconv_handle, plato_upper,
1647 : plato_lower) == 0,
1648 : "case insensitive comparison upper/lower");
1649 0 : return true;
1650 : }
1651 :
1652 2 : static bool test_gd(struct torture_context *tctx)
1653 : {
1654 2 : DATA_BLOB gd_utf8 = base64_decode_data_blob(gd_utf8_base64);
1655 2 : DATA_BLOB gd_cp850 = base64_decode_data_blob(gd_cp850_base64);
1656 2 : DATA_BLOB gd_iso8859_1 = base64_decode_data_blob(gd_iso8859_1_base64);
1657 2 : DATA_BLOB gd_utf16le = base64_decode_data_blob(gd_utf16le_base64);
1658 2 : DATA_BLOB gd_output;
1659 2 : size_t saved_len;
1660 :
1661 2 : talloc_steal(tctx, gd_utf8.data);
1662 2 : talloc_steal(tctx, gd_cp850.data);
1663 2 : talloc_steal(tctx, gd_iso8859_1.data);
1664 2 : talloc_steal(tctx, gd_utf16le.data);
1665 :
1666 2 : torture_assert(tctx, convert_string_talloc(tctx, CH_UTF8, CH_UTF8,
1667 : gd_utf8.data, gd_utf8.length,
1668 : (void *)&gd_output.data, &gd_output.length),
1669 : "conversion from UTF8 to utf8 charset");
1670 2 : saved_len = gd_output.length;
1671 :
1672 2 : torture_assert(tctx, convert_string_error(CH_UTF8, CH_UTF8,
1673 : gd_utf8.data, gd_utf8.length,
1674 : (void *)gd_output.data, gd_output.length,
1675 : &gd_output.length),
1676 : "conversion from UTF8 to utf8 charset");
1677 :
1678 : /* Short output handling confirmation */
1679 2 : gd_output.length = 1;
1680 2 : torture_assert(tctx, convert_string_error(CH_UTF8, CH_UTF8,
1681 : gd_utf8.data, gd_utf8.length,
1682 : (void *)gd_output.data, gd_output.length,
1683 : &gd_output.length) == false,
1684 : "conversion from UTF8 to any utf8 charset should fail due to too short");
1685 2 : torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to utf8 charset should fail E2BIG");
1686 2 : torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
1687 2 : torture_assert_data_blob_equal(tctx, gd_output, data_blob_string_const("G"), "conversion from UTF8 to utf8 charset incorrect");
1688 :
1689 : #if 0 /* This currently fails as we just copy like-for-like character conversions */
1690 : /* Short output handling confirmation */
1691 : gd_output.length = 2;
1692 : torture_assert(tctx, convert_string_error(CH_UTF8, CH_UTF8,
1693 : gd_utf8.data, gd_utf8.length,
1694 : (void *)gd_output.data, gd_output.length,
1695 : &gd_output.length) == false,
1696 : "conversion from UTF8 to utf8 charset should fail due to too short");
1697 : torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to utf8 charset should fail E2BIG");
1698 : torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
1699 :
1700 : /* Short input handling confirmation */
1701 : gd_output.length = saved_len;
1702 : torture_assert(tctx, convert_string_error(CH_UTF8, CH_UTF8,
1703 : gd_utf8.data, 2,
1704 : (void *)gd_output.data, gd_output.length,
1705 : &gd_output.length) == false,
1706 : "conversion from UTF8 to UTF8 should fail due to too short");
1707 : torture_assert_errno_equal(tctx, EILSEQ, "conversion from short UTF8 to UTF8 should fail EINVAL");
1708 : torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
1709 : #endif
1710 :
1711 : /* Short output handling confirmation */
1712 2 : gd_output.length = 1;
1713 2 : torture_assert(tctx, convert_string_error(CH_UTF16LE, CH_UTF8,
1714 : gd_utf16le.data, gd_utf16le.length,
1715 : (void *)gd_output.data, gd_output.length,
1716 : &gd_output.length) == false,
1717 : "conversion from UTF16 to UTF8 should fail due to too short");
1718 2 : torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16 to UTF8 should fail E2BIG");
1719 2 : torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
1720 2 : torture_assert_data_blob_equal(tctx, gd_output, data_blob_string_const("G"), "conversion from UTF16 to UTF8 incorrect");
1721 :
1722 : /* Short output handling confirmation */
1723 2 : gd_output.length = 3;
1724 2 : torture_assert(tctx, convert_string_error(CH_UTF16LE, CH_UTF8,
1725 : gd_utf16le.data, gd_utf16le.length,
1726 : (void *)gd_output.data, gd_output.length,
1727 : &gd_output.length) == false,
1728 : "conversion from UTF16 to UTF8 should fail due to too short");
1729 2 : torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16 to UTF8 should fail E2BIG");
1730 2 : torture_assert_int_equal(tctx, gd_output.length, 3, "Should get 3 bytes output for UTF8");
1731 :
1732 : /* Short input handling confirmation */
1733 2 : gd_output.length = saved_len;
1734 2 : torture_assert(tctx, convert_string_error(CH_UTF16LE, CH_UTF8,
1735 : gd_utf16le.data, 3,
1736 : (void *)gd_output.data, gd_output.length,
1737 : &gd_output.length) == false,
1738 : "conversion from UTF16 to UTF8 should fail due to too short");
1739 2 : torture_assert_errno_equal(tctx, EINVAL, "conversion from short UTF16 to UTF8 should fail EINVAL");
1740 2 : torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
1741 :
1742 0 : return true;
1743 : }
1744 :
1745 2 : static bool test_plato(struct torture_context *tctx)
1746 : {
1747 2 : DATA_BLOB plato_utf8 = base64_decode_data_blob(plato_utf8_base64);
1748 2 : DATA_BLOB plato_utf16le = base64_decode_data_blob(plato_utf16le_base64);
1749 2 : DATA_BLOB plato_output;
1750 2 : DATA_BLOB plato_output2;
1751 :
1752 2 : talloc_steal(tctx, plato_utf8.data);
1753 2 : talloc_steal(tctx, plato_utf16le.data);
1754 :
1755 2 : torture_assert(tctx, convert_string_talloc(tctx,
1756 : CH_UTF8, CH_UTF16LE,
1757 : plato_utf8.data, plato_utf8.length,
1758 : (void *)&plato_output.data, &plato_output.length),
1759 : "conversion of UTF8 ancient greek to UTF16 failed");
1760 2 : torture_assert_data_blob_equal(tctx, plato_output, plato_utf16le, "conversion from UTF8 to UTF16LE incorrect");
1761 :
1762 2 : torture_assert_int_equal(tctx,
1763 : strlen_m_ext((const char *)plato_utf8.data,
1764 : CH_UTF8, CH_UTF16LE),
1765 : plato_output.length / 2,
1766 : "checking strlen_m_ext of conversion of UTF8 to UTF16LE");
1767 :
1768 2 : memset(plato_output.data, '\0', plato_output.length);
1769 2 : torture_assert(tctx, convert_string_error(CH_UTF8, CH_UTF16LE,
1770 : plato_utf8.data, plato_utf8.length,
1771 : (void *)plato_output.data, plato_output.length,
1772 : &plato_output.length),
1773 : "conversion of UTF8 ancient greek to UTF16 failed");
1774 2 : torture_assert_data_blob_equal(tctx, plato_output, plato_utf16le, "conversion from UTF8 to UTF16LE incorrect");
1775 :
1776 2 : torture_assert(tctx, convert_string_talloc(tctx,
1777 : CH_UTF16LE, CH_UTF8,
1778 : plato_output.data, plato_output.length,
1779 : (void *)&plato_output2.data, &plato_output2.length),
1780 : "conversion of UTF8 ancient greek to UTF16 failed");
1781 2 : torture_assert_data_blob_equal(tctx, plato_output2, plato_utf8, "conversion from UTF8 to UTF16LE incorrect");
1782 :
1783 2 : memset(plato_output2.data, '\0', plato_output2.length);
1784 2 : torture_assert(tctx, convert_string_error(CH_UTF16LE, CH_UTF8,
1785 : plato_output.data, plato_output.length,
1786 : (void *)plato_output2.data, plato_output2.length, &plato_output2.length),
1787 : "conversion of UTF8 ancient greek to UTF16 failed");
1788 2 : torture_assert_data_blob_equal(tctx, plato_output2, plato_utf8, "conversion from UTF8 to UTF16LE incorrect");
1789 :
1790 2 : torture_assert(tctx, convert_string_talloc(tctx,
1791 : CH_UTF8, CH_UTF8,
1792 : plato_utf8.data, plato_utf8.length,
1793 : (void *)&plato_output.data, &plato_output.length),
1794 : "conversion of UTF8 to UTF8");
1795 2 : torture_assert_data_blob_equal(tctx, plato_output, plato_utf8,
1796 : "conversion of UTF8 to UTF8");
1797 2 : torture_assert_int_equal(tctx,
1798 : strlen_m_ext((const char *)plato_utf8.data,
1799 : CH_UTF8, CH_UTF8),
1800 : plato_output.length,
1801 : "checking strlen_m_ext of conversion of UTF8 to UTF8");
1802 2 : memset(plato_output.data, '\0', plato_output.length);
1803 2 : torture_assert(tctx, convert_string_error(CH_UTF8, CH_UTF8,
1804 : plato_utf8.data, plato_utf8.length,
1805 : (void *)plato_output.data, plato_output.length,
1806 : &plato_output.length),
1807 : "conversion of UTF8 to UTF8");
1808 2 : torture_assert_data_blob_equal(tctx, plato_output, plato_utf8,
1809 : "conversion of UTF8 to UTF8");
1810 :
1811 2 : memset(plato_output.data, '\0', plato_output.length);
1812 2 : torture_assert(tctx, convert_string_error(CH_UTF8, CH_DOS,
1813 : plato_utf8.data, plato_utf8.length,
1814 : (void *)plato_output.data, plato_output.length,
1815 : &plato_output.length) == false,
1816 : "conversion of UTF8 to any dos charset should fail");
1817 2 : torture_assert_errno_equal(tctx, EILSEQ, "conversion of UTF16 ancient greek to any DOS charset should fail EILSEQ");
1818 :
1819 2 : torture_assert(tctx, convert_string_talloc(tctx,
1820 : CH_UTF8, CH_DOS,
1821 : plato_utf8.data, plato_utf8.length,
1822 : (void *)&plato_output.data, &plato_output.length) == false,
1823 : "conversion of UTF8 ancient greek to any DOS charset should fail");
1824 :
1825 : /* Allocate only enough space for a partial conversion */
1826 2 : plato_output = data_blob_talloc(tctx, NULL, 9);
1827 2 : torture_assert(tctx, convert_string_error(CH_UTF16LE, CH_UTF8,
1828 : plato_utf16le.data, plato_utf16le.length,
1829 : (void *)plato_output.data, plato_output.length,
1830 : &plato_output.length) == false,
1831 : "conversion of UTF16 ancient greek to UTF8 should fail, not enough space");
1832 2 : torture_assert_errno_equal(tctx, E2BIG, "conversion of UTF16 ancient greek to UTF8 should fail, not enough space");
1833 2 : torture_assert_int_equal(tctx, plato_output.length, 8,
1834 : "conversion of UTF16 ancient greek to UTF8 should stop on multibyte boundary");
1835 :
1836 2 : plato_output = data_blob_talloc(tctx, NULL, 2);
1837 2 : torture_assert(tctx, convert_string_error(CH_UTF16LE, CH_UTF8,
1838 : plato_utf16le.data, plato_utf16le.length,
1839 : (void *)plato_output.data, plato_output.length,
1840 : &plato_output.length) == false,
1841 : "conversion of UTF16 ancient greek to UTF8 should fail, not enough space");
1842 2 : torture_assert_errno_equal(tctx, E2BIG, "conversion of UTF16 ancient greek to UTF8 should fail, not enough space");
1843 2 : torture_assert_int_equal(tctx, plato_output.length, 0,
1844 : "conversion of UTF16 ancient greek to UTF8 should stop on multibyte boundary");
1845 :
1846 :
1847 0 : return true;
1848 : }
1849 :
1850 :
1851 :
1852 2 : static bool test_short_strings(struct torture_context *tctx)
1853 : {
1854 2 : char zeros[6] = {0};
1855 2 : char s[6] = {'s'};
1856 2 : bool ok;
1857 2 : char *out;
1858 2 : size_t out_len;
1859 :
1860 2 : ok = convert_string_talloc(tctx,
1861 : CH_UTF8, CH_UTF16LE,
1862 : zeros, 0,
1863 : &out, &out_len);
1864 2 : torture_assert(tctx, ok, "{\"\", 0} to utf16 failed");
1865 2 : torture_assert(tctx, out_len == 2, "{\"\", 0} length is two");
1866 2 : torture_assert(tctx, out[0] == 0 && out[1] == 0, "{\"\", 0} utf16 is zero");
1867 2 : TALLOC_FREE(out);
1868 :
1869 2 : ok = convert_string_talloc(tctx,
1870 : CH_UTF8, CH_UTF16LE,
1871 : zeros, 1,
1872 : &out, &out_len);
1873 2 : torture_assert(tctx, ok, "{\"\\0\", 1} to utf16 failed");
1874 2 : torture_assert(tctx, out_len == 2, "{\"\\0\", 1} length is two");
1875 2 : torture_assert(tctx, out[0] == 0 && out[1] == 0, "{\"\\0\", 1} utf16 is zero");
1876 2 : TALLOC_FREE(out);
1877 :
1878 2 : ok = convert_string_talloc(tctx,
1879 : CH_UTF8, CH_UTF16LE,
1880 : zeros, 2,
1881 : &out, &out_len);
1882 2 : torture_assert(tctx, ok, "{\"\\0\\0\", 2} to utf16 failed");
1883 2 : torture_assert(tctx, out_len == 4, "{\"\\0\\0\", 2} length is four");
1884 2 : torture_assert(tctx, out[0] == 0 && out[1] == 0, "{\"\\0\\0\", 2} utf16 is zero");
1885 2 : TALLOC_FREE(out);
1886 :
1887 2 : ok = convert_string_talloc(tctx,
1888 : CH_UTF8, CH_UTF16LE,
1889 : s, 0,
1890 : &out, &out_len);
1891 2 : torture_assert(tctx, ok, "{\"s\", 0} to utf16 failed");
1892 2 : torture_assert(tctx, out_len == 2, "{\"s\", 0} length is two");
1893 2 : torture_assert(tctx, out[0] == 0 && out[1] == 0,
1894 : "{\"s\", 0} utf16 is zero");
1895 2 : TALLOC_FREE(out);
1896 :
1897 2 : ok = convert_string_talloc(tctx,
1898 : CH_UTF8, CH_UTF16LE,
1899 : s, 1,
1900 : &out, &out_len);
1901 2 : torture_assert(tctx, ok, "{\"s\", 1} to utf16 failed");
1902 2 : torture_assert(tctx, out_len == 2, "{\"s\", 1} length is two");
1903 2 : torture_assert(tctx, out[0] == 's' && out[1] == 0,
1904 : "{\"s\", 1} utf16 is s");
1905 2 : TALLOC_FREE(out);
1906 :
1907 2 : ok = convert_string_talloc(tctx,
1908 : CH_UTF8, CH_UTF16LE,
1909 : s, 2,
1910 : &out, &out_len);
1911 2 : torture_assert(tctx, ok, "{\"s\\0\", 2} to utf16 failed");
1912 2 : torture_assert(tctx, out_len == 4, "{\"s\\0\", 2} length is four");
1913 2 : torture_assert(tctx, out[0] == 's' && out[1] == 0,
1914 : "{\"s\\0\", 0} utf16 is s");
1915 2 : TALLOC_FREE(out);
1916 :
1917 :
1918 : /* going to utf8 */
1919 2 : ok = convert_string_talloc(tctx,
1920 : CH_UTF16LE, CH_UTF8,
1921 : zeros, 0,
1922 : &out, &out_len);
1923 2 : torture_assert(tctx, ok, "{\"\", 0} to utf8 failed");
1924 2 : torture_assert(tctx, out_len == 1, "{\"\", 0} length is one");
1925 2 : torture_assert(tctx, out[0] == 0, "{\"\", 0} utf8[0] is zero");
1926 2 : TALLOC_FREE(out);
1927 :
1928 2 : ok = convert_string_talloc(tctx,
1929 : CH_UTF16LE, CH_UTF8,
1930 : zeros, 2,
1931 : &out, &out_len);
1932 2 : torture_assert(tctx, ok, "{\"\\0\", 1} to utf8 failed");
1933 2 : torture_assert(tctx, out_len == 1, "{\"\\0\", 1} length is one");
1934 2 : torture_assert(tctx, out[0] == 0 && out[1] == 0,
1935 : "{\"\\0\", 1} utf8 is zero");
1936 2 : TALLOC_FREE(out);
1937 :
1938 2 : ok = convert_string_talloc(tctx,
1939 : CH_UTF16LE, CH_UTF8,
1940 : zeros, 4,
1941 : &out, &out_len);
1942 2 : torture_assert(tctx, ok, "{\"\\0\\0\\0\\0\", 4} to utf8 failed");
1943 2 : torture_assert(tctx, out_len == 2, "{\"\\0\\0\\0\\0\", 4} length is two");
1944 2 : torture_assert(tctx, out[0] == 0 && out[1] == 0,
1945 : "{\"\\0\\0\\0\\0\", 4} utf8 is zero");
1946 2 : TALLOC_FREE(out);
1947 :
1948 2 : ok = convert_string_talloc(tctx,
1949 : CH_UTF16LE, CH_UTF8,
1950 : s, 0,
1951 : &out, &out_len);
1952 2 : torture_assert(tctx, ok, "{\"s\", 0} to utf8 failed");
1953 2 : torture_assert(tctx, out_len == 1, "{\"s\", 0} length is one");
1954 2 : torture_assert(tctx, out[0] == 0, "{\"s\", 0} utf8 is zero");
1955 2 : TALLOC_FREE(out);
1956 :
1957 2 : ok = convert_string_talloc(tctx,
1958 : CH_UTF16LE, CH_UTF8,
1959 : s, 2,
1960 : &out, &out_len);
1961 2 : torture_assert(tctx, ok, "{\"s\\0\", 2} to utf8 failed");
1962 2 : torture_assert(tctx, out_len == 1, "{\"s\\0\", 2} length is one");
1963 2 : torture_assert(tctx, out[0] == 's' && out[1] == 0,
1964 : "{\"s\\0\", 2} utf8 is s");
1965 2 : TALLOC_FREE(out);
1966 :
1967 :
1968 2 : ok = convert_string_talloc(tctx,
1969 : CH_UTF16LE, CH_UTF8,
1970 : s, 4,
1971 : &out, &out_len);
1972 2 : torture_assert(tctx, ok, "{\"s\\0\\0\\0\", 4} utf8 failed");
1973 2 : torture_assert(tctx, out_len == 2, "\"s\\0\\0\\0\", 4} utf8 length is two");
1974 2 : torture_assert(tctx, out[0] == 's' && out[1] == 0,
1975 : "{\"s\\0\\0\\0\", 4} utf8 is s");
1976 2 : TALLOC_FREE(out);
1977 :
1978 : /* odd numbers of bytes from UTF-16 should fail */
1979 2 : ok = convert_string_talloc(tctx,
1980 : CH_UTF16LE, CH_UTF8,
1981 : s, 1,
1982 : &out, &out_len);
1983 2 : torture_assert(tctx, ! ok, "{\"s\", 1} to utf8 should have failed");
1984 :
1985 2 : ok = convert_string_talloc(tctx,
1986 : CH_UTF16LE, CH_UTF8,
1987 : s, 3,
1988 : &out, &out_len);
1989 2 : torture_assert(tctx, ! ok, "{\"s\\0\\0\", 3} to utf8 should have failed");
1990 :
1991 2 : ok = convert_string_talloc(tctx,
1992 : CH_UTF16LE, CH_UTF8,
1993 : zeros, 1,
1994 : &out, &out_len);
1995 2 : torture_assert(tctx, ! ok,
1996 : "{\"\\0\", 1} to utf8 should have failed");
1997 :
1998 2 : ok = convert_string_talloc(tctx,
1999 : CH_UTF16LE, CH_UTF8,
2000 : zeros, 5,
2001 : &out, &out_len);
2002 2 : torture_assert(tctx, ! ok,
2003 : "{\"\\0\\0\\0\\0\", 5} to utf8 should have failed");
2004 :
2005 0 : return true;
2006 : }
2007 :
2008 :
2009 2 : static bool test_plato_latin(struct torture_context *tctx)
2010 : {
2011 2 : DATA_BLOB plato_latin_utf8 = base64_decode_data_blob(plato_latin_utf8_base64);
2012 2 : DATA_BLOB plato_latin_utf16le = base64_decode_data_blob(plato_latin_utf16le_base64);
2013 2 : DATA_BLOB plato_latin_output;
2014 :
2015 2 : talloc_steal(tctx, plato_latin_utf8.data);
2016 2 : talloc_steal(tctx, plato_latin_utf16le.data);
2017 :
2018 2 : torture_assert(tctx, convert_string_talloc(tctx,
2019 : CH_UTF16LE, CH_UTF8,
2020 : plato_latin_utf16le.data, plato_latin_utf16le.length,
2021 : (void *)&plato_latin_output.data, &plato_latin_output.length),
2022 : "conversion of UTF16 latin charset greek to unix charset UTF8 failed");
2023 2 : torture_assert_data_blob_equal(tctx, plato_latin_output, plato_latin_utf8, "conversion from UTF16 to UTF8 incorrect");
2024 :
2025 2 : torture_assert_int_equal(tctx,
2026 : strlen_m_ext((const char *)plato_latin_output.data,
2027 : CH_UTF8, CH_UTF16LE),
2028 : plato_latin_utf16le.length / 2,
2029 : "checking strlen_m_ext UTF16 latin charset greek to UTF8");
2030 2 : torture_assert(tctx, convert_string_talloc(tctx,
2031 : CH_UTF8, CH_UTF16LE,
2032 : plato_latin_utf8.data, plato_latin_utf8.length,
2033 : (void *)&plato_latin_output.data, &plato_latin_output.length),
2034 : "conversion of UTF16 latin charset greek to UTF16LE failed");
2035 2 : torture_assert_data_blob_equal(tctx, plato_latin_output, plato_latin_utf16le, "conversion from UTF8 to UTF16LE incorrect");
2036 :
2037 0 : return true;
2038 : }
2039 :
2040 2 : static bool test_gd_case(struct torture_context *tctx)
2041 : {
2042 2 : DATA_BLOB gd_utf8 = base64_decode_data_blob(gd_utf8_base64);
2043 2 : char *gd_unix;
2044 2 : size_t gd_size;
2045 2 : char *gd_lower, *gd_upper;
2046 2 : talloc_steal(tctx, gd_utf8.data);
2047 :
2048 2 : torture_assert(tctx, convert_string_talloc(tctx, CH_UTF8, CH_UNIX,
2049 : gd_utf8.data, gd_utf8.length,
2050 : (void *)&gd_unix, &gd_size),
2051 : "conversion of unix charset to UTF8");
2052 :
2053 2 : gd_lower = strlower_talloc(tctx, gd_unix);
2054 2 : torture_assert(tctx, gd_lower, "failed to convert GD's name into lower case");
2055 2 : gd_upper = strupper_talloc_n(tctx, gd_unix, gd_size);
2056 2 : torture_assert(tctx, gd_lower, "failed to convert GD's name into upper case");
2057 :
2058 2 : torture_assert(tctx,
2059 : strhasupper(gd_unix),
2060 : "GD's name has an upper case character");
2061 2 : torture_assert(tctx,
2062 : strhaslower(gd_unix),
2063 : "GD's name has an lower case character");
2064 2 : torture_assert(tctx,
2065 : strhasupper(gd_upper),
2066 : "upper case name has an upper case character");
2067 2 : torture_assert(tctx,
2068 : strhaslower(gd_lower),
2069 : "lower case name has an lower case character");
2070 2 : torture_assert(tctx,
2071 : strhasupper(gd_lower) == false,
2072 : "lower case name has no upper case character");
2073 2 : torture_assert(tctx,
2074 : strhaslower(gd_upper) == false,
2075 : "upper case name has no lower case character");
2076 :
2077 2 : torture_assert(tctx, strcasecmp_m(gd_unix,
2078 : gd_upper) == 0,
2079 : "case insensitive comparison orig/upper");
2080 2 : torture_assert(tctx, strcasecmp_m(gd_unix,
2081 : gd_lower) == 0,
2082 : "case insensitive comparison orig/lower");
2083 2 : torture_assert(tctx, strcasecmp_m(gd_upper,
2084 : gd_lower) == 0,
2085 : "case insensitive comparison upper/lower");
2086 :
2087 : /* This string isn't different in length upper/lower, but just check the first 5 chars */
2088 2 : torture_assert(tctx, strncasecmp_m(gd_unix,
2089 : gd_upper, 5) == 0,
2090 : "case insensitive comparison orig/upper");
2091 2 : torture_assert(tctx, strncasecmp_m(gd_unix,
2092 : gd_lower, 5) == 0,
2093 : "case insensitive comparison orig/lower");
2094 2 : torture_assert(tctx, strncasecmp_m(gd_upper,
2095 : gd_lower, 5) == 0,
2096 : "case insensitive comparison upper/lower");
2097 0 : return true;
2098 : }
2099 :
2100 2 : static bool test_plato_case(struct torture_context *tctx)
2101 : {
2102 2 : DATA_BLOB plato_utf8 = base64_decode_data_blob(plato_utf8_base64);
2103 2 : char *plato_unix;
2104 2 : size_t plato_length;
2105 2 : char *plato_lower, *plato_upper;
2106 2 : talloc_steal(tctx, plato_utf8.data);
2107 :
2108 2 : torture_assert(tctx, convert_string_talloc(tctx, CH_UTF8, CH_UNIX,
2109 : plato_utf8.data, plato_utf8.length,
2110 : (void *)&plato_unix, &plato_length),
2111 : "conversion of unix charset to UTF8");
2112 :
2113 2 : torture_assert(tctx,
2114 : strhasupper(plato_unix),
2115 : "PLATO's apology has an upper case character");
2116 2 : torture_assert(tctx,
2117 : strhaslower(plato_unix),
2118 : "PLATO's apology has an lower case character");
2119 2 : plato_lower = strlower_talloc(tctx, plato_unix);
2120 2 : torture_assert(tctx, plato_lower, "failed to convert PLATO's apology into lower case");
2121 2 : plato_upper = strupper_talloc_n(tctx, plato_unix, plato_utf8.length);
2122 2 : torture_assert(tctx, plato_lower, "failed to convert PLATO's apology into upper case");
2123 :
2124 2 : torture_assert(tctx,
2125 : strhasupper(plato_upper),
2126 : "upper case string has an upper case character");
2127 2 : torture_assert(tctx,
2128 : strhaslower(plato_lower),
2129 : "lower case string has an lower case character");
2130 2 : torture_assert(tctx,
2131 : strhasupper(plato_lower) == false,
2132 : "lower case string has no upper case character");
2133 2 : torture_assert(tctx,
2134 : strhaslower(plato_upper) == false,
2135 : "upper case string has no lower case character");
2136 :
2137 2 : torture_assert(tctx, strcasecmp_m(plato_unix,
2138 : plato_upper) == 0,
2139 : "case insensitive comparison orig/upper");
2140 2 : torture_assert(tctx, strcasecmp_m(plato_unix,
2141 : plato_lower) == 0,
2142 : "case insensitive comparison orig/lower");
2143 2 : torture_assert(tctx, strcasecmp_m(plato_upper,
2144 : plato_lower) == 0,
2145 : "case insensitive comparison upper/lower");
2146 0 : return true;
2147 : }
2148 :
2149 2354 : struct torture_suite *torture_local_convert_string_handle(TALLOC_CTX *mem_ctx)
2150 : {
2151 2354 : struct torture_suite *suite = torture_suite_create(mem_ctx, "convert_string_handle");
2152 2354 : torture_suite_add_simple_test(suite, "cp850 high points", test_cp850_high_points);
2153 :
2154 2354 : torture_suite_add_simple_test(suite, "gd_ascii", test_gd_ascii_handle);
2155 2354 : torture_suite_add_simple_test(suite, "gd_minus_1", test_gd_minus_1_handle);
2156 2354 : torture_suite_add_simple_test(suite, "gd_iso8859_cp850", test_gd_iso8859_cp850_handle);
2157 2354 : torture_suite_add_simple_test(suite, "plato_english_iso8859_cp850", test_plato_english_iso8859_cp850_handle);
2158 2354 : torture_suite_add_simple_test(suite, "plato_english_minus_1", test_plato_english_minus_1_handle);
2159 2354 : torture_suite_add_simple_test(suite, "plato_cp850_utf8", test_plato_cp850_utf8_handle);
2160 2354 : torture_suite_add_simple_test(suite, "plato_minus_1", test_plato_minus_1_handle);
2161 2354 : torture_suite_add_simple_test(suite, "plato_latin_cp850_utf8", test_plato_latin_cp850_utf8_handle);
2162 2354 : torture_suite_add_simple_test(suite, "utf8-nfc-to-nfd", test_utf8_nfc_to_nfd);
2163 2354 : torture_suite_add_simple_test(suite, "utf8-nfc-to-nfd-overflow", test_utf8_nfc_to_nfd_overflow);
2164 2354 : torture_suite_add_simple_test(suite, "utf8-nfd-to-nfc", test_utf8_nfd_to_nfc);
2165 2354 : return suite;
2166 : }
2167 :
2168 2354 : struct torture_suite *torture_local_string_case_handle(TALLOC_CTX *mem_ctx)
2169 : {
2170 2354 : struct torture_suite *suite = torture_suite_create(mem_ctx, "string_case_handle");
2171 :
2172 2354 : torture_suite_add_simple_test(suite, "gd_case_utf8", test_gd_case_utf8_handle);
2173 2354 : torture_suite_add_simple_test(suite, "gd_case_cp850", test_gd_case_cp850_handle);
2174 2354 : torture_suite_add_simple_test(suite, "plato_case_utf8", test_plato_case_utf8_handle);
2175 2354 : return suite;
2176 : }
2177 :
2178 2354 : struct torture_suite *torture_local_convert_string(TALLOC_CTX *mem_ctx)
2179 : {
2180 2354 : struct torture_suite *suite = torture_suite_create(mem_ctx, "convert_string");
2181 :
2182 2354 : torture_suite_add_simple_test(suite, "short_strings", test_short_strings);
2183 2354 : torture_suite_add_simple_test(suite, "gd", test_gd);
2184 2354 : torture_suite_add_simple_test(suite, "plato", test_plato);
2185 2354 : torture_suite_add_simple_test(suite, "plato_latin", test_plato_latin);
2186 2354 : return suite;
2187 : }
2188 :
2189 2354 : struct torture_suite *torture_local_string_case(TALLOC_CTX *mem_ctx)
2190 : {
2191 2354 : struct torture_suite *suite = torture_suite_create(mem_ctx, "string_case_handle");
2192 :
2193 2354 : torture_suite_add_simple_test(suite, "gd_case", test_gd_case);
2194 2354 : torture_suite_add_simple_test(suite, "plato_case", test_plato_case);
2195 2354 : return suite;
2196 : }
|