util/charset/torture: test convert_string_talloc with emptyish strings
[Samba.git] / lib / util / charset / tests / convert_string.c
blob6400ce15625c5760d3d6a34c6327f78db879b07b
1 /*
2 Unix SMB/CIFS implementation.
3 test suite for the charcnv functions
5 Copyright (C) Andrew Bartlett 2011
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.
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.
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/>.
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"
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);
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
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.";
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=";
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==";
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=";
74 static const char *plato_latin_utf8_base64 =
75 "SMOzdGkgbcOobiBodW1lw65zLCDDtCDDoW5kcmVzIEF0aMSTbmHDrm9pLCBwZXDDs250aGF0ZSBo"
76 "dXDDsiB0w7RuIGVtw7RuIGthdMSTZ8OzcsWNbiwgb3VrIG/DrmRhOiBlZ+G5kSBkJyBvw7tuIGth"
77 "w6wgYXV0w7JzIGh1cCcgYXV0xY1uIG9sw61nb3UgZW1hdXRvw7sgZXBlbGF0aMOzbcSTbiwgaG/D"
78 "unTFjSBwaXRoYW7DtHMgw6lsZWdvbi4gS2HDrXRvaSBhbMSTdGjDqXMgZ2UgaMWNcyDDqXBvcyBl"
79 "aXBlw65uIG91ZMOobiBlaXLhuJdrYXNpbi4=";
81 static const char *plato_latin_utf16le_base64 =
82 "SADzAHQAaQAgAG0A6ABuACAAaAB1AG0AZQDuAHMALAAgAPQAIADhAG4AZAByAGUAcwAgAEEAdABo"
83 "ABMBbgBhAO4AbwBpACwAIABwAGUAcADzAG4AdABoAGEAdABlACAAaAB1AHAA8gAgAHQA9ABuACAA"
84 "ZQBtAPQAbgAgAGsAYQB0ABMBZwDzAHIATQFuACwAIABvAHUAawAgAG8A7gBkAGEAOgAgAGUAZwBR"
85 "HiAAZAAnACAAbwD7AG4AIABrAGEA7AAgAGEAdQB0APIAcwAgAGgAdQBwACcAIABhAHUAdABNAW4A"
86 "IABvAGwA7QBnAG8AdQAgAGUAbQBhAHUAdABvAPsAIABlAHAAZQBsAGEAdABoAPMAbQATAW4ALAAg"
87 "AGgAbwD6AHQATQEgAHAAaQB0AGgAYQBuAPQAcwAgAOkAbABlAGcAbwBuAC4AIABLAGEA7QB0AG8A"
88 "aQAgAGEAbAATAXQAaADpAHMAIABnAGUAIABoAE0BcwAgAOkAcABvAHMAIABlAGkAcABlAO4AbgAg"
89 "AG8AdQBkAOgAbgAgAGUAaQByABceawBhAHMAaQBuAC4A";
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==";
105 * These cp850 bytes correspond to high Unicode codes, stretching out to
106 * 3-byte sequences in utf-8.
108 static const char *cp850_high_points = "\xb9\xba\xbb\xbc\xcd\xce";
109 static const char *utf8_high_points = "╣║╗╝═╬";
111 static bool test_cp850_high_points(struct torture_context *tctx)
113 struct smb_iconv_handle *iconv_handle = NULL;
114 DATA_BLOB cp850 = data_blob_string_const(cp850_high_points);
115 DATA_BLOB utf8;
116 DATA_BLOB cp850_return;
118 iconv_handle = get_iconv_testing_handle(tctx, "CP850", "UTF8",
119 lpcfg_parm_bool(tctx->lp_ctx,
120 NULL,
121 "iconv",
122 "use_builtin_handlers",
123 true));
125 torture_assert(tctx, iconv_handle, "creating iconv handle");
127 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");
134 torture_assert(tctx, utf8.length == cp850.length * 3,
135 "CP850 high bytes expand to the right size");
137 torture_assert(tctx,
138 memcmp(utf8.data, utf8_high_points, utf8.length) == 0,
139 "cp850 converted to utf8 matches expected value");
141 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");
149 torture_assert(tctx, data_blob_cmp(&cp850_return, &cp850) == 0,
150 "UTF-8 returned to CP850 matches the original");
151 return true;
155 static bool test_gd_iso8859_cp850_handle(struct torture_context *tctx)
157 struct smb_iconv_handle *iconv_handle;
158 DATA_BLOB gd_utf8 = base64_decode_data_blob(gd_utf8_base64);
159 DATA_BLOB gd_cp850 = base64_decode_data_blob(gd_cp850_base64);
160 DATA_BLOB gd_iso8859_1 = base64_decode_data_blob(gd_iso8859_1_base64);
161 DATA_BLOB gd_utf16le = base64_decode_data_blob(gd_utf16le_base64);
162 DATA_BLOB gd_output;
163 DATA_BLOB gd_output2;
165 talloc_steal(tctx, gd_utf8.data);
166 talloc_steal(tctx, gd_cp850.data);
167 talloc_steal(tctx, gd_iso8859_1.data);
168 talloc_steal(tctx, gd_utf16le.data);
170 iconv_handle = get_iconv_testing_handle(tctx, "ISO-8859-1", "CP850",
171 lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
172 torture_assert(tctx, iconv_handle, "getting iconv handle");
174 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 torture_assert_data_blob_equal(tctx, gd_output, gd_iso8859_1, "conversion from UTF8 to (dos charset) ISO-8859-1 incorrect");
181 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 torture_assert_data_blob_equal(tctx, gd_output, gd_iso8859_1, "conversion from UTF8 to (dos charset) ISO-8859-1 incorrect");
189 /* Short output handling confirmation */
190 gd_output.length = 1;
191 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 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to (dos charset) ISO-8859-1 should fail E2BIG");
198 torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
199 torture_assert_data_blob_equal(tctx, gd_output, data_blob_string_const("G"), "conversion from UTF8 to (dos charset) ISO-8859-1 incorrect");
201 /* Short output handling confirmation */
202 gd_output.length = 2;
203 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 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to (dos charset) ISO-8859-1 should fail E2BIG");
210 torture_assert_int_equal(tctx, gd_output.length, 2, "Should only get 2 char of output");
212 /* Short input handling confirmation */
213 gd_output.length = gd_iso8859_1.length;
214 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 torture_assert_errno_equal(tctx, EILSEQ, "conversion from short UTF8 to (dos charset) ISO-8859-1 should fail EINVAL");
221 torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
223 /* Short output handling confirmation */
224 gd_output.length = 1;
225 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 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16 to (utf8 charset) ISO-8859-1 should fail E2BIG");
232 torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
233 torture_assert_data_blob_equal(tctx, gd_output, data_blob_string_const("G"), "conversion from UTF16 to UTF8 incorrect");
235 /* Short output handling confirmation */
236 gd_output.length = 3;
237 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 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16 to (utf8 charset) ISO-8859-1 should fail E2BIG");
244 torture_assert_int_equal(tctx, gd_output.length, 3, "Should get 3 bytes output for UTF8");
246 /* Short input handling confirmation */
247 gd_output.length = gd_utf8.length;
248 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 torture_assert_errno_equal(tctx, EINVAL, "conversion from short UTF16 to UTF8 should fail EINVAL");
255 torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
257 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 torture_assert_data_blob_equal(tctx, gd_output, gd_cp850, "conversion from UTF8 to (unix charset) CP850 incorrect");
264 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 torture_assert_data_blob_equal(tctx, gd_output, gd_utf8, "conversion from UTF8 to UTF8 incorrect");
271 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 torture_assert_data_blob_equal(tctx, gd_output, gd_iso8859_1, "conversion from UTF16LE to (dos charset) ISO-8859-1 incorrect");
278 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 torture_assert_data_blob_equal(tctx, gd_output2, gd_utf16le, "round trip conversion from (dos charset) ISO-8859-1 back to UTF16LE");
285 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 torture_assert_data_blob_equal(tctx, gd_output, gd_cp850, "conversion from UTF16LE to (unix charset) CP850 incorrect");
292 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 torture_assert_data_blob_equal(tctx, gd_output, gd_utf8, "conversion from UTF16LE to UTF8 incorrect");
299 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 torture_assert_data_blob_equal(tctx, gd_output, gd_iso8859_1, "conversion from UTF16LE to (dos charset) ISO-8859-1 incorrect");
306 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 torture_assert_data_blob_equal(tctx, gd_output, gd_cp850, "conversion from UTF16LE to (unix charset) CP850 incorrect");
313 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 torture_assert_data_blob_equal(tctx, gd_output, gd_utf8, "conversion from UTF16LE to UTF8 incorrect");
320 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 torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le, "conversion from (dos charset) ISO-8859-1 to UTF16LE");
326 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");
333 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 torture_assert_data_blob_equal(tctx, gd_output, gd_utf8, "conversion from (dos charset) ISO-8859-1 to UTF8");
339 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 return true;
348 static bool test_gd_minus_1_handle(struct torture_context *tctx)
350 struct smb_iconv_handle *iconv_handle;
351 DATA_BLOB gd_utf8 = base64_decode_data_blob(gd_utf8_base64);
352 DATA_BLOB gd_cp850 = base64_decode_data_blob(gd_cp850_base64);
353 DATA_BLOB gd_utf16le = base64_decode_data_blob(gd_utf16le_base64);
354 DATA_BLOB gd_output;
355 DATA_BLOB gd_utf8_terminated;
356 DATA_BLOB gd_cp850_terminated;
357 DATA_BLOB gd_utf16le_terminated;
359 talloc_steal(tctx, gd_utf8.data);
360 talloc_steal(tctx, gd_cp850.data);
361 talloc_steal(tctx, gd_utf16le.data);
363 iconv_handle = get_iconv_testing_handle(tctx, "CP850", "CP850",
364 lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
365 torture_assert(tctx, iconv_handle, "getting iconv handle");
367 gd_utf8_terminated = data_blob_talloc(tctx, NULL, gd_utf8.length + 1);
368 memcpy(gd_utf8_terminated.data, gd_utf8.data, gd_utf8.length);
369 gd_utf8_terminated.data[gd_utf8.length] = '\0';
371 gd_cp850_terminated = data_blob_talloc(tctx, NULL, gd_cp850.length + 1);
372 memcpy(gd_cp850_terminated.data, gd_cp850.data, gd_cp850.length);
373 gd_cp850_terminated.data[gd_cp850.length] = '\0';
375 gd_utf16le_terminated = data_blob_talloc(tctx, NULL, gd_utf16le.length + 2);
376 memcpy(gd_utf16le_terminated.data, gd_utf16le.data, gd_utf16le.length);
377 gd_utf16le_terminated.data[gd_utf16le.length] = '\0';
378 gd_utf16le_terminated.data[gd_utf16le.length + 1] = '\0';
380 gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
382 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 torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated");
389 gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
390 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 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
396 torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le, "conversion from UTF8 to UTF16LE null terminated");
398 gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
399 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 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
406 gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
407 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 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
414 gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10);
415 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 torture_assert_data_blob_equal(tctx, gd_output, gd_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated");
422 gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10);
424 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 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
430 torture_assert_data_blob_equal(tctx, gd_output, gd_utf8, "conversion from UTF16LE to UTF8 null terminated");
432 gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10);
434 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 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
441 gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10);
443 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 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
450 gd_output = data_blob_talloc(tctx, NULL, gd_cp850.length + 10);
452 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 torture_assert_data_blob_equal(tctx, gd_output, gd_cp850_terminated, "conversion from UTF16LE to CP850 (dos) null terminated");
459 /* Now null terminate the string early, the confirm we don't skip the NULL and convert any further */
460 gd_utf8_terminated.data[3] = '\0';
461 gd_utf8_terminated.length = 4; /* used for the comparison only */
463 gd_cp850_terminated.data[2] = '\0';
464 gd_cp850_terminated.length = 3; /* used for the comparison only */
466 gd_utf16le_terminated.data[4] = '\0';
467 gd_utf16le_terminated.data[5] = '\0';
468 gd_utf16le_terminated.length = 6; /* used for the comparison only */
470 gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
472 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 torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated early");
479 gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10);
481 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 torture_assert_data_blob_equal(tctx, gd_output, gd_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated early");
488 gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
490 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 torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated early");
497 gd_output = data_blob_talloc(tctx, NULL, gd_cp850.length + 10);
499 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 torture_assert_data_blob_equal(tctx, gd_output, gd_cp850_terminated, "conversion from UTF16LE to UTF8 null terminated early");
506 /* Now null terminate the string particularly early, the confirm we don't skip the NULL and convert any further */
507 gd_utf8_terminated.data[1] = '\0';
508 gd_utf8_terminated.length = 2; /* used for the comparison only */
510 gd_utf16le_terminated.data[2] = '\0';
511 gd_utf16le_terminated.data[3] = '\0';
512 gd_utf16le_terminated.length = 4; /* used for the comparison only */
514 gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
516 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 torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated very early");
522 gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10);
524 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 torture_assert_data_blob_equal(tctx, gd_output, gd_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated very early");
531 return true;
534 static bool test_gd_ascii_handle(struct torture_context *tctx)
536 struct smb_iconv_handle *iconv_handle;
537 DATA_BLOB gd_utf8 = base64_decode_data_blob(gd_utf8_base64);
538 DATA_BLOB gd_cp850 = base64_decode_data_blob(gd_cp850_base64);
539 DATA_BLOB gd_iso8859_1 = base64_decode_data_blob(gd_iso8859_1_base64);
540 DATA_BLOB gd_utf16le = base64_decode_data_blob(gd_utf16le_base64);
541 DATA_BLOB gd_output;
543 talloc_steal(tctx, gd_utf8.data);
544 talloc_steal(tctx, gd_cp850.data);
545 talloc_steal(tctx, gd_iso8859_1.data);
546 talloc_steal(tctx, gd_utf16le.data);
548 iconv_handle = get_iconv_testing_handle(tctx, "ASCII", "UTF8",
549 lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
550 torture_assert(tctx, iconv_handle, "getting iconv handle");
552 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");
558 gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length);
560 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 torture_assert_errno_equal(tctx, EILSEQ, "conversion from UTF8 to (dos charset) ISO-8859-1 should fail E2BIG");
567 torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
568 torture_assert_data_blob_equal(tctx, gd_output, data_blob_string_const("G"), "partial conversion from UTF8 to (dos charset) ASCII incorrect");
570 /* Short output handling confirmation */
571 gd_output.length = 1;
572 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 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to (dos charset) ASCII too short");
579 torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
580 torture_assert_data_blob_equal(tctx, gd_output, data_blob_string_const("G"), "conversion from UTF8 to (dos charset) ASCII incorrect");
582 /* Short output handling confirmation */
583 gd_output.length = 2;
584 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 torture_assert_errno_equal(tctx, EILSEQ, "conversion from UTF8 to (dos charset) ISO-8859-1 should fail EILSEQ");
591 torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 2 char of output");
593 /* Short input handling confirmation */
594 gd_output.length = gd_utf8.length;
595 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 torture_assert_errno_equal(tctx, EILSEQ, "conversion from short UTF8 to (dos charset) ASCII should fail EILSEQ");
602 torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
603 return true;
606 static bool test_plato_english_iso8859_cp850_handle(struct torture_context *tctx)
608 struct smb_iconv_handle *iconv_handle;
609 DATA_BLOB plato_english_utf8 = data_blob_string_const(plato_english_ascii);
610 DATA_BLOB plato_english_cp850 = plato_english_utf8;
611 DATA_BLOB plato_english_iso8859_1 = plato_english_utf8;
612 DATA_BLOB plato_english_utf16le = base64_decode_data_blob(plato_english_utf16le_base64);
613 DATA_BLOB plato_english_output;
614 DATA_BLOB plato_english_output2;
616 talloc_steal(tctx, plato_english_utf16le.data);
618 iconv_handle = get_iconv_testing_handle(tctx, "ISO-8859-1", "CP850",
619 lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
620 torture_assert(tctx, iconv_handle, "getting iconv handle");
622 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 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_iso8859_1, "conversion from UTF8 to (dos charset) ISO-8859-1 incorrect");
629 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 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_cp850, "conversion from UTF8 to (unix charset) CP850 incorrect");
636 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 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF8 to UTF8 incorrect");
643 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 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_iso8859_1, "conversion from UTF16LE to (dos charset) ISO-8859-1 incorrect");
650 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 torture_assert_data_blob_equal(tctx, plato_english_output2, plato_english_utf16le, "round trip conversion from (dos charset) ISO-8859-1 back to UTF16LE");
657 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 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF16LE to UTF8 incorrect");
664 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 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF16LE to UTF8 incorrect");
672 plato_english_output.length = 5;
673 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 torture_assert_data_blob_equal(tctx, plato_english_output, data_blob_string_const("What "), "conversion from UTF16LE to UTF8 incorrect");
680 torture_assert_int_equal(tctx, plato_english_output.length, 5, "short conversion failed");
682 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 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_cp850, "conversion from UTF16LE to (unix charset) CP850 incorrect");
689 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 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF16LE to UTF8 incorrect");
696 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 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_iso8859_1, "conversion from UTF16LE to (dos charset) ISO-8859-1 incorrect");
703 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 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_cp850, "conversion from UTF16LE to (unix charset) CP850 incorrect");
710 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 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF16LE to UTF8 incorrect");
717 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 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf16le, "conversion from (dos charset) ISO-8859-1 to UTF16LE");
723 return true;
726 static bool test_plato_english_minus_1_handle(struct torture_context *tctx)
728 struct smb_iconv_handle *iconv_handle;
729 DATA_BLOB plato_english_utf8 = data_blob_string_const(plato_english_ascii);
730 DATA_BLOB plato_english_utf16le = base64_decode_data_blob(plato_english_utf16le_base64);
731 DATA_BLOB plato_english_output;
732 DATA_BLOB plato_english_utf8_terminated;
733 DATA_BLOB plato_english_utf16le_terminated;
735 talloc_steal(tctx, plato_english_utf16le.data);
737 iconv_handle = get_iconv_testing_handle(tctx, "ISO-8859-1", "CP850",
738 lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
739 torture_assert(tctx, iconv_handle, "getting iconv handle");
741 plato_english_utf8_terminated = data_blob_talloc(tctx, NULL, plato_english_utf8.length + 1);
742 memcpy(plato_english_utf8_terminated.data, plato_english_utf8.data, plato_english_utf8.length);
743 plato_english_utf8_terminated.data[plato_english_utf8.length] = '\0';
745 plato_english_utf16le_terminated = data_blob_talloc(tctx, NULL, plato_english_utf16le.length + 2);
746 memcpy(plato_english_utf16le_terminated.data, plato_english_utf16le.data, plato_english_utf16le.length);
747 plato_english_utf16le_terminated.data[plato_english_utf16le.length] = '\0';
748 plato_english_utf16le_terminated.data[plato_english_utf16le.length + 1] = '\0';
750 plato_english_output = data_blob_talloc(tctx, NULL, plato_english_utf16le.length + 10);
752 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 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated");
759 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 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
765 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf16le, "conversion from UTF8 to UTF16LE null terminated");
767 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 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
774 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 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
781 plato_english_output = data_blob_talloc(tctx, NULL, plato_english_utf8.length + 10);
783 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 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated");
790 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 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
796 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF16LE to UTF8 null terminated");
798 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 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
805 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 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
812 /* Now null terminate the string early, the confirm we don't skip the NULL and convert any further */
813 plato_english_utf8_terminated.data[3] = '\0';
814 plato_english_utf8_terminated.length = 4; /* used for the comparison only */
816 plato_english_utf16le_terminated.data[6] = '\0';
817 plato_english_utf16le_terminated.data[7] = '\0';
818 plato_english_utf16le_terminated.length = 8; /* used for the comparison only */
820 plato_english_output = data_blob_talloc(tctx, NULL, plato_english_utf16le.length + 10);
822 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 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated early");
829 plato_english_output = data_blob_talloc(tctx, NULL, plato_english_utf8.length + 10);
831 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 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated early");
839 /* Now null terminate the string particularly early, the confirm we don't skip the NULL and convert any further */
840 plato_english_utf8_terminated.data[1] = '\0';
841 plato_english_utf8_terminated.length = 2; /* used for the comparison only */
843 plato_english_utf16le_terminated.data[2] = '\0';
844 plato_english_utf16le_terminated.data[3] = '\0';
845 plato_english_utf16le_terminated.length = 4; /* used for the comparison only */
847 plato_english_output = data_blob_talloc(tctx, NULL, plato_english_utf16le.length + 10);
849 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 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated very early");
855 plato_english_output = data_blob_talloc(tctx, NULL, plato_english_utf8.length + 10);
857 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 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated very early");
864 return true;
867 static bool test_plato_minus_1_handle(struct torture_context *tctx)
869 struct smb_iconv_handle *iconv_handle;
870 DATA_BLOB plato_utf8 = base64_decode_data_blob(plato_utf8_base64);
871 DATA_BLOB plato_utf16le = base64_decode_data_blob(plato_utf16le_base64);
872 DATA_BLOB plato_output;
873 DATA_BLOB plato_utf8_terminated;
874 DATA_BLOB plato_utf16le_terminated;
876 talloc_steal(tctx, plato_utf8.data);
877 talloc_steal(tctx, plato_utf16le.data);
879 iconv_handle = get_iconv_testing_handle(tctx, "ISO-8859-1", "CP850",
880 lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
881 torture_assert(tctx, iconv_handle, "getting iconv handle");
883 plato_utf8_terminated = data_blob_talloc(tctx, NULL, plato_utf8.length + 1);
884 memcpy(plato_utf8_terminated.data, plato_utf8.data, plato_utf8.length);
885 plato_utf8_terminated.data[plato_utf8.length] = '\0';
887 plato_utf16le_terminated = data_blob_talloc(tctx, NULL, plato_utf16le.length + 2);
888 memcpy(plato_utf16le_terminated.data, plato_utf16le.data, plato_utf16le.length);
889 plato_utf16le_terminated.data[plato_utf16le.length] = '\0';
890 plato_utf16le_terminated.data[plato_utf16le.length + 1] = '\0';
892 plato_output = data_blob_talloc(tctx, NULL, plato_utf16le.length + 10);
894 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 torture_assert_data_blob_equal(tctx, plato_output, plato_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated");
901 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 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
907 torture_assert_data_blob_equal(tctx, plato_output, plato_utf16le, "conversion from UTF8 to UTF16LE null terminated");
909 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 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
916 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 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
923 plato_output = data_blob_talloc(tctx, NULL, plato_utf8.length + 10);
925 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 torture_assert_data_blob_equal(tctx, plato_output, plato_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated");
932 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 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
938 torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF16LE to UTF8 null terminated");
940 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 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
947 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 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
954 /* Now null terminate the string early, the confirm we don't skip the NULL and convert any further */
955 plato_utf8_terminated.data[5] = '\0';
956 plato_utf8_terminated.length = 6; /* used for the comparison only */
958 plato_utf16le_terminated.data[4] = '\0';
959 plato_utf16le_terminated.data[5] = '\0';
960 plato_utf16le_terminated.length = 6; /* used for the comparison only */
962 plato_output = data_blob_talloc(tctx, NULL, plato_utf16le.length + 10);
964 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 torture_assert_data_blob_equal(tctx, plato_output, plato_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated early");
971 plato_output = data_blob_talloc(tctx, NULL, plato_utf8.length + 10);
973 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 torture_assert_data_blob_equal(tctx, plato_output, plato_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated early");
980 return true;
983 static bool test_plato_cp850_utf8_handle(struct torture_context *tctx)
985 struct smb_iconv_handle *iconv_handle;
986 DATA_BLOB plato_utf8 = base64_decode_data_blob(plato_utf8_base64);
987 DATA_BLOB plato_utf16le = base64_decode_data_blob(plato_utf16le_base64);
988 DATA_BLOB plato_output;
989 DATA_BLOB plato_output2;
991 talloc_steal(tctx, plato_utf8.data);
992 talloc_steal(tctx, plato_utf16le.data);
994 iconv_handle = get_iconv_testing_handle(tctx, "CP850", "UTF8",
995 lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
996 torture_assert(tctx, iconv_handle, "creating iconv handle");
998 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 torture_assert_data_blob_equal(tctx, plato_output, plato_utf16le, "conversion from UTF8 to UTF16LE incorrect");
1005 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");
1012 memset(plato_output.data, '\0', plato_output.length);
1013 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 torture_assert_data_blob_equal(tctx, plato_output, plato_utf16le, "conversion from UTF8 to UTF16LE incorrect");
1021 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 torture_assert_data_blob_equal(tctx, plato_output2, plato_utf8, "conversion from UTF8 to UTF16LE incorrect");
1028 memset(plato_output2.data, '\0', plato_output2.length);
1029 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 torture_assert_data_blob_equal(tctx, plato_output2, plato_utf8, "conversion from UTF8 to UTF16LE incorrect");
1036 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 torture_assert_data_blob_equal(tctx, plato_output, plato_utf8,
1042 "conversion of UTF8 to UTF8");
1043 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 memset(plato_output.data, '\0', plato_output.length);
1050 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");
1057 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");
1063 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 torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF8 to (unix charset) UTF8 incorrect");
1070 memset(plato_output.data, '\0', plato_output.length);
1071 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 torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF8 to (unix charset) UTF8 incorrect");
1079 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 torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF8 to UTF8 incorrect");
1086 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");
1092 /* Allocate enough space, if it were possible do do the conversion */
1093 plato_output = data_blob_talloc(tctx, NULL, plato_utf16le.length);
1094 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 torture_assert_errno_equal(tctx, EILSEQ, "conversion of UTF16 ancient greek to DOS charset CP850 should fail");
1102 /* Allocate only enough space for a partial conversion */
1103 plato_output = data_blob_talloc(tctx, NULL, 9);
1104 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 torture_assert_errno_equal(tctx, E2BIG, "conversion of UTF16 ancient greek to UTF8 should fail, not enough space");
1111 torture_assert_int_equal(tctx, plato_output.length, 8,
1112 "conversion of UTF16 ancient greek to UTF8 should stop on multibyte boundary");
1114 plato_output = data_blob_talloc(tctx, NULL, 2);
1115 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 torture_assert_errno_equal(tctx, E2BIG, "conversion of UTF16 ancient greek to UTF8 should fail, not enough space");
1122 torture_assert_int_equal(tctx, plato_output.length, 0,
1123 "conversion of UTF16 ancient greek to UTF8 should stop on multibyte boundary");
1126 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 torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF16LE to (unix charset) UTF8 incorrect");
1132 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 torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF16LE to UTF8 incorrect");
1138 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 torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF16LE to UTF8 incorrect");
1145 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 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 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");
1159 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 torture_assert_data_blob_equal(tctx, plato_output2, plato_utf8,
1165 "conversion of UTF8 to UTF8");
1166 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 return true;
1175 static bool test_plato_latin_cp850_utf8_handle(struct torture_context *tctx)
1177 struct smb_iconv_handle *iconv_handle;
1178 DATA_BLOB plato_latin_utf8 = base64_decode_data_blob(plato_latin_utf8_base64);
1179 DATA_BLOB plato_latin_utf16le = base64_decode_data_blob(plato_latin_utf16le_base64);
1180 DATA_BLOB plato_latin_output;
1181 DATA_BLOB plato_latin_output2;
1183 talloc_steal(tctx, plato_latin_utf8.data);
1184 talloc_steal(tctx, plato_latin_utf16le.data);
1186 iconv_handle = get_iconv_testing_handle(tctx, "CP850", "UTF8",
1187 lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
1188 torture_assert(tctx, iconv_handle, "creating iconv handle");
1190 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");
1196 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 torture_assert_data_blob_equal(tctx, plato_latin_output, plato_latin_utf8, "conversion from UTF8 to (unix charset) UTF8 incorrect");
1203 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 torture_assert_data_blob_equal(tctx, plato_latin_output, plato_latin_utf8, "conversion from UTF8 to UTF8 incorrect");
1210 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");
1216 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 torture_assert_data_blob_equal(tctx, plato_latin_output, plato_latin_utf8, "conversion from UTF16LE to (unix charset) CP850 incorrect");
1223 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 torture_assert_data_blob_equal(tctx, plato_latin_output, plato_latin_utf8, "conversion from UTF16LE to UTF8 incorrect");
1230 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 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 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 return true;
1246 static bool test_utf8_nfc_to_nfd_overflow(struct torture_context *tctx)
1248 smb_iconv_t ic;
1249 DATA_BLOB utf8_nfc_blob;
1250 DATA_BLOB utf8_nfd_blob;
1251 DATA_BLOB src_blob;
1252 DATA_BLOB blob;
1253 size_t nconv;
1254 const char *src = NULL;
1255 char *dst = NULL;
1256 size_t dst_left;
1257 size_t srclen;
1258 bool ret = true;
1260 ic = smb_iconv_open("UTF8-NFD", "UTF8-NFC");
1261 torture_assert_goto(tctx, ic != (smb_iconv_t)-1, ret, done,
1262 "creating iconv handle\n");
1264 utf8_nfc_blob = base64_decode_data_blob_talloc(tctx, utf8_nfc_base64);
1265 torture_assert_not_null_goto(tctx, utf8_nfc_blob.data, ret, done,
1266 "OOM\n");
1268 utf8_nfd_blob = base64_decode_data_blob_talloc(tctx, utf8_nfd_base64);
1269 torture_assert_not_null_goto(tctx, utf8_nfd_blob.data, ret, done,
1270 "OOM\n");
1272 blob = data_blob_talloc_zero(tctx, 255);
1273 torture_assert_not_null_goto(tctx, blob.data, ret, done, "OOM\n");
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().
1281 src = "foo";
1282 srclen = 3;
1283 dst = (char *)blob.data;
1284 dst_left = 0;
1285 nconv = smb_iconv(ic,
1286 &src,
1287 &srclen,
1288 &dst,
1289 &dst_left);
1290 torture_assert_int_equal_goto(tctx, nconv, -1, ret, done,
1291 "smb_iconv failed\n");
1292 torture_assert_errno_equal_goto(tctx, EINVAL, ret, done,
1293 "Wrong errno\n");
1295 src = "foo";
1296 srclen = 3;
1297 dst = (char *)blob.data;
1298 dst_left = 1;
1299 nconv = smb_iconv(ic,
1300 &src,
1301 &srclen,
1302 &dst,
1303 &dst_left);
1304 torture_assert_int_equal_goto(tctx, nconv, -1, ret, done,
1305 "smb_iconv failed\n");
1306 torture_assert_errno_equal_goto(tctx, EINVAL, ret, done,
1307 "Wrong errno\n");
1309 src = "foo";
1310 srclen = 3;
1311 dst = (char *)blob.data;
1312 dst_left = 2;
1313 nconv = smb_iconv(ic,
1314 &src,
1315 &srclen,
1316 &dst,
1317 &dst_left);
1318 torture_assert_int_equal_goto(tctx, nconv, -1, ret, done,
1319 "smb_iconv failed\n");
1320 torture_assert_errno_equal_goto(tctx, EINVAL, ret, done,
1321 "Wrong errno\n");
1323 src_blob = data_blob_const("foo", 3);
1324 src = (const char *)src_blob.data;
1325 srclen = src_blob.length;
1326 dst = (char *)blob.data;
1327 dst_left = 3;
1328 nconv = smb_iconv(ic,
1329 &src,
1330 &srclen,
1331 &dst,
1332 &dst_left);
1333 torture_assert_int_equal_goto(tctx, nconv, 3, ret, done,
1334 "smb_iconv failed\n");
1336 blob.length = nconv;
1337 torture_assert_data_blob_equal(tctx,
1338 src_blob,
1339 blob,
1340 "Conversion failed\n");
1342 src_blob = data_blob_const("foo", 4);
1343 src = (const char *)src_blob.data;
1344 srclen = src_blob.length;
1345 dst = (char *)blob.data;
1346 dst_left = 4;
1347 nconv = smb_iconv(ic,
1348 &src,
1349 &srclen,
1350 &dst,
1351 &dst_left);
1352 torture_assert_int_equal_goto(tctx, nconv, 4, ret, done,
1353 "smb_iconv failed\n");
1355 blob.length = nconv;
1356 torture_assert_data_blob_equal(tctx,
1357 src_blob,
1358 blob,
1359 "Conversion failed\n");
1361 done:
1362 return ret;
1365 static bool test_utf8_nfc_to_nfd(struct torture_context *tctx)
1367 smb_iconv_t ic;
1368 DATA_BLOB utf8_nfc_blob;
1369 DATA_BLOB utf8_nfd_blob;
1370 DATA_BLOB blob;
1371 size_t nconv;
1372 const char *src = NULL;
1373 char *dst = NULL;
1374 size_t dst_left;
1375 size_t srclen;
1376 bool ret = true;
1378 ic = smb_iconv_open("UTF8-NFD", "UTF8-NFC");
1379 torture_assert_goto(tctx, ic != (smb_iconv_t)-1, ret, done,
1380 "creating iconv handle\n");
1382 utf8_nfc_blob = base64_decode_data_blob_talloc(tctx, utf8_nfc_base64);
1383 torture_assert_not_null_goto(tctx, utf8_nfc_blob.data, ret, done,
1384 "OOM\n");
1386 utf8_nfd_blob = base64_decode_data_blob_talloc(tctx, utf8_nfd_base64);
1387 torture_assert_not_null_goto(tctx, utf8_nfd_blob.data, ret, done,
1388 "OOM\n");
1390 blob = data_blob_talloc_zero(tctx, 255);
1391 torture_assert_not_null_goto(tctx, blob.data, ret, done, "OOM\n");
1393 dst = (char *)blob.data;
1394 dst_left = blob.length;
1395 src = (const char *)utf8_nfc_blob.data;
1396 srclen = strlen(src);
1398 nconv = smb_iconv(ic,
1399 &src,
1400 &srclen,
1401 &dst,
1402 &dst_left);
1403 torture_assert_goto(tctx, nconv != (size_t)-1, ret, done,
1404 "smb_iconv failed\n");
1406 blob.length = nconv + 1; /* +1 for the trailing zero */
1407 torture_assert_data_blob_equal(tctx,
1408 blob,
1409 utf8_nfd_blob,
1410 "Conversion failed\n");
1412 done:
1413 return ret;
1416 static bool test_utf8_nfd_to_nfc(struct torture_context *tctx)
1418 smb_iconv_t ic;
1419 DATA_BLOB utf8_nfc_blob;
1420 DATA_BLOB utf8_nfd_blob;
1421 DATA_BLOB blob;
1422 size_t nconv;
1423 const char *src = NULL;
1424 char *dst = NULL;
1425 size_t dst_left;
1426 size_t srclen;
1427 bool ret = true;
1429 ic = smb_iconv_open("UTF8-NFC", "UTF8-NFD");
1430 torture_assert_goto(tctx, ic != (smb_iconv_t)-1, ret, done,
1431 "creating iconv handle\n");
1433 utf8_nfc_blob = base64_decode_data_blob_talloc(tctx, utf8_nfc_base64);
1434 torture_assert_not_null_goto(tctx, utf8_nfc_blob.data, ret, done,
1435 "OOM\n");
1437 utf8_nfd_blob = base64_decode_data_blob_talloc(tctx, utf8_nfd_base64);
1438 torture_assert_not_null_goto(tctx, utf8_nfd_blob.data, ret, done,
1439 "OOM\n");
1441 blob = data_blob_talloc_zero(tctx, 255);
1442 torture_assert_not_null_goto(tctx, blob.data, ret, done, "OOM\n");
1444 dst = (char *)blob.data;
1445 dst_left = blob.length;
1446 src = (const char *)utf8_nfd_blob.data;
1447 srclen = strlen(src);
1449 nconv = smb_iconv(ic,
1450 &src,
1451 &srclen,
1452 &dst,
1453 &dst_left);
1454 torture_assert_goto(tctx, nconv != (size_t)-1, ret, done,
1455 "smb_iconv failed\n");
1457 blob.length = nconv + 1; /* +1 for the trailing zero */
1458 torture_assert_data_blob_equal(tctx,
1459 blob,
1460 utf8_nfc_blob,
1461 "Conversion failed\n");
1463 done:
1464 return ret;
1467 static bool test_gd_case_utf8_handle(struct torture_context *tctx)
1469 struct smb_iconv_handle *iconv_handle;
1470 DATA_BLOB gd_utf8 = base64_decode_data_blob(gd_utf8_base64);
1471 DATA_BLOB gd_utf8_upper = base64_decode_data_blob(gd_utf8_upper_base64);
1472 DATA_BLOB gd_utf8_lower = base64_decode_data_blob(gd_utf8_lower_base64);
1473 char *gd_lower, *gd_upper;
1474 talloc_steal(tctx, gd_utf8.data);
1476 iconv_handle = get_iconv_testing_handle(tctx, "ASCII", "UTF8",
1477 lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
1478 torture_assert(tctx, iconv_handle, "getting utf8 iconv handle");
1480 torture_assert(tctx,
1481 strhasupper_handle(iconv_handle, (const char *)gd_utf8.data),
1482 "GD's name has an upper case character");
1483 torture_assert(tctx,
1484 strhaslower_handle(iconv_handle, (const char *)gd_utf8.data),
1485 "GD's name has an lower case character");
1486 gd_lower = strlower_talloc_handle(iconv_handle, tctx, (const char *)gd_utf8.data);
1487 torture_assert(tctx, gd_lower, "failed to convert GD's name into lower case");
1488 torture_assert_data_blob_equal(tctx, data_blob_string_const(gd_lower), gd_utf8_lower,
1489 "convert GD's name into lower case");
1490 gd_upper = strupper_talloc_n_handle(iconv_handle, tctx, (const char *)gd_utf8.data, gd_utf8.length);
1491 torture_assert(tctx, gd_lower, "failed to convert GD's name into upper case");
1492 torture_assert_data_blob_equal(tctx, data_blob_string_const(gd_upper), gd_utf8_upper,
1493 "convert GD's name into upper case");
1495 torture_assert(tctx,
1496 strhasupper_handle(iconv_handle, gd_upper),
1497 "upper case name has an upper case character");
1498 torture_assert(tctx,
1499 strhaslower_handle(iconv_handle, gd_lower),
1500 "lower case name has an lower case character");
1501 torture_assert(tctx,
1502 strhasupper_handle(iconv_handle, gd_lower) == false,
1503 "lower case name has no upper case character");
1504 torture_assert(tctx,
1505 strhaslower_handle(iconv_handle, gd_upper) == false,
1506 "upper case name has no lower case character");
1508 torture_assert(tctx, strcasecmp_m_handle(iconv_handle, (const char *)gd_utf8.data,
1509 gd_upper) == 0,
1510 "case insensitive comparison orig/upper");
1511 torture_assert(tctx, strcasecmp_m_handle(iconv_handle, (const char *)gd_utf8.data,
1512 gd_lower) == 0,
1513 "case insensitive comparison orig/lower");
1514 torture_assert(tctx, strcasecmp_m_handle(iconv_handle, gd_upper,
1515 gd_lower) == 0,
1516 "case insensitive comparison upper/lower");
1518 /* This string isn't different in length upper/lower */
1519 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 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 torture_assert(tctx, strncasecmp_m_handle(iconv_handle, gd_upper,
1526 gd_lower, gd_utf8.length) == 0,
1527 "case insensitive comparison upper/lower");
1529 data_blob_free(&gd_utf8);
1530 data_blob_free(&gd_utf8_upper);
1531 data_blob_free(&gd_utf8_lower);
1533 return true;
1536 static bool test_gd_case_cp850_handle(struct torture_context *tctx)
1538 struct smb_iconv_handle *iconv_handle;
1539 DATA_BLOB gd_cp850 = base64_decode_data_blob(gd_cp850_base64);
1540 DATA_BLOB gd_cp850_upper = base64_decode_data_blob(gd_cp850_upper_base64);
1541 DATA_BLOB gd_cp850_lower = base64_decode_data_blob(gd_cp850_lower_base64);
1542 char *gd_lower, *gd_upper;
1543 talloc_steal(tctx, gd_cp850.data);
1545 iconv_handle = get_iconv_testing_handle(tctx, "ASCII", "CP850",
1546 lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
1547 torture_assert(tctx, iconv_handle, "getting cp850 iconv handle");
1549 torture_assert(tctx,
1550 strhasupper_handle(iconv_handle, (const char *)gd_cp850.data),
1551 "GD's name has an upper case character");
1552 torture_assert(tctx,
1553 strhaslower_handle(iconv_handle, (const char *)gd_cp850.data),
1554 "GD's name has an lower case character");
1555 gd_lower = strlower_talloc_handle(iconv_handle, tctx, (const char *)gd_cp850.data);
1556 torture_assert(tctx, gd_lower, "failed to convert GD's name into lower case");
1557 torture_assert_data_blob_equal(tctx, data_blob_string_const(gd_lower), gd_cp850_lower,
1558 "convert GD's name into lower case");
1559 gd_upper = strupper_talloc_n_handle(iconv_handle, tctx, (const char *)gd_cp850.data, gd_cp850.length);
1560 torture_assert(tctx, gd_lower, "failed to convert GD's name into upper case");
1561 torture_assert_data_blob_equal(tctx, data_blob_string_const(gd_upper), gd_cp850_upper,
1562 "convert GD's name into upper case");
1564 torture_assert(tctx,
1565 strhasupper_handle(iconv_handle, gd_upper),
1566 "upper case name has an upper case character");
1567 torture_assert(tctx,
1568 strhaslower_handle(iconv_handle, gd_lower),
1569 "lower case name has an lower case character");
1570 torture_assert(tctx,
1571 strhasupper_handle(iconv_handle, gd_lower) == false,
1572 "lower case name has no upper case character");
1573 torture_assert(tctx,
1574 strhaslower_handle(iconv_handle, gd_upper) == false,
1575 "upper case name has no lower case character");
1577 torture_assert(tctx, strcasecmp_m_handle(iconv_handle, (const char *)gd_cp850.data,
1578 gd_upper) == 0,
1579 "case insensitive comparison orig/upper");
1580 torture_assert(tctx, strcasecmp_m_handle(iconv_handle, (const char *)gd_cp850.data,
1581 gd_lower) == 0,
1582 "case insensitive comparison orig/lower");
1583 torture_assert(tctx, strcasecmp_m_handle(iconv_handle, gd_upper,
1584 gd_lower) == 0,
1585 "case insensitive comparison upper/lower");
1587 /* This string isn't different in length upper/lower */
1588 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 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 torture_assert(tctx, strncasecmp_m_handle(iconv_handle, gd_upper,
1595 gd_lower, gd_cp850.length) == 0,
1596 "case insensitive comparison upper/lower");
1598 data_blob_free(&gd_cp850);
1599 data_blob_free(&gd_cp850_upper);
1600 data_blob_free(&gd_cp850_lower);
1602 return true;
1605 static bool test_plato_case_utf8_handle(struct torture_context *tctx)
1607 struct smb_iconv_handle *iconv_handle;
1608 DATA_BLOB plato_utf8 = base64_decode_data_blob(plato_utf8_base64);
1609 char *plato_lower, *plato_upper;
1610 talloc_steal(tctx, plato_utf8.data);
1612 iconv_handle = get_iconv_testing_handle(tctx, "ASCII", "UTF8",
1613 lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
1614 torture_assert(tctx, iconv_handle, "getting utf8 iconv handle");
1616 torture_assert(tctx,
1617 strhasupper_handle(iconv_handle, (const char *)plato_utf8.data),
1618 "PLATO's apology has an upper case character");
1619 torture_assert(tctx,
1620 strhaslower_handle(iconv_handle, (const char *)plato_utf8.data),
1621 "PLATO's apology has an lower case character");
1622 plato_lower = strlower_talloc_handle(iconv_handle, tctx, (const char *)plato_utf8.data);
1623 torture_assert(tctx, plato_lower, "failed to convert PLATO's apology into lower case");
1624 plato_upper = strupper_talloc_n_handle(iconv_handle, tctx, (const char *)plato_utf8.data, plato_utf8.length);
1625 torture_assert(tctx, plato_lower, "failed to convert PLATO's apology into upper case");
1627 torture_assert(tctx,
1628 strhasupper_handle(iconv_handle, plato_upper),
1629 "upper case string has an upper case character");
1630 torture_assert(tctx,
1631 strhaslower_handle(iconv_handle, plato_lower),
1632 "lower case string has an lower case character");
1633 torture_assert(tctx,
1634 strhasupper_handle(iconv_handle, plato_lower) == false,
1635 "lower case string has no upper case character");
1636 torture_assert(tctx,
1637 strhaslower_handle(iconv_handle, plato_upper) == false,
1638 "upper case string has no lower case character");
1640 torture_assert(tctx, strcasecmp_m_handle(iconv_handle, (const char *)plato_utf8.data,
1641 plato_upper) == 0,
1642 "case insensitive comparison orig/upper");
1643 torture_assert(tctx, strcasecmp_m_handle(iconv_handle, (const char *)plato_utf8.data,
1644 plato_lower) == 0,
1645 "case insensitive comparison orig/lower");
1646 torture_assert(tctx, strcasecmp_m_handle(iconv_handle, plato_upper,
1647 plato_lower) == 0,
1648 "case insensitive comparison upper/lower");
1649 return true;
1652 static bool test_gd(struct torture_context *tctx)
1654 DATA_BLOB gd_utf8 = base64_decode_data_blob(gd_utf8_base64);
1655 DATA_BLOB gd_cp850 = base64_decode_data_blob(gd_cp850_base64);
1656 DATA_BLOB gd_iso8859_1 = base64_decode_data_blob(gd_iso8859_1_base64);
1657 DATA_BLOB gd_utf16le = base64_decode_data_blob(gd_utf16le_base64);
1658 DATA_BLOB gd_output;
1659 size_t saved_len;
1661 talloc_steal(tctx, gd_utf8.data);
1662 talloc_steal(tctx, gd_cp850.data);
1663 talloc_steal(tctx, gd_iso8859_1.data);
1664 talloc_steal(tctx, gd_utf16le.data);
1666 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 saved_len = gd_output.length;
1672 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");
1678 /* Short output handling confirmation */
1679 gd_output.length = 1;
1680 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 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to utf8 charset should fail E2BIG");
1686 torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
1687 torture_assert_data_blob_equal(tctx, gd_output, data_blob_string_const("G"), "conversion from UTF8 to utf8 charset incorrect");
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");
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
1711 /* Short output handling confirmation */
1712 gd_output.length = 1;
1713 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 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16 to UTF8 should fail E2BIG");
1719 torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
1720 torture_assert_data_blob_equal(tctx, gd_output, data_blob_string_const("G"), "conversion from UTF16 to UTF8 incorrect");
1722 /* Short output handling confirmation */
1723 gd_output.length = 3;
1724 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 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16 to UTF8 should fail E2BIG");
1730 torture_assert_int_equal(tctx, gd_output.length, 3, "Should get 3 bytes output for UTF8");
1732 /* Short input handling confirmation */
1733 gd_output.length = saved_len;
1734 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 torture_assert_errno_equal(tctx, EINVAL, "conversion from short UTF16 to UTF8 should fail EINVAL");
1740 torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
1742 return true;
1745 static bool test_plato(struct torture_context *tctx)
1747 DATA_BLOB plato_utf8 = base64_decode_data_blob(plato_utf8_base64);
1748 DATA_BLOB plato_utf16le = base64_decode_data_blob(plato_utf16le_base64);
1749 DATA_BLOB plato_output;
1750 DATA_BLOB plato_output2;
1752 talloc_steal(tctx, plato_utf8.data);
1753 talloc_steal(tctx, plato_utf16le.data);
1755 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 torture_assert_data_blob_equal(tctx, plato_output, plato_utf16le, "conversion from UTF8 to UTF16LE incorrect");
1762 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");
1768 memset(plato_output.data, '\0', plato_output.length);
1769 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 torture_assert_data_blob_equal(tctx, plato_output, plato_utf16le, "conversion from UTF8 to UTF16LE incorrect");
1776 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 torture_assert_data_blob_equal(tctx, plato_output2, plato_utf8, "conversion from UTF8 to UTF16LE incorrect");
1783 memset(plato_output2.data, '\0', plato_output2.length);
1784 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 torture_assert_data_blob_equal(tctx, plato_output2, plato_utf8, "conversion from UTF8 to UTF16LE incorrect");
1790 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 torture_assert_data_blob_equal(tctx, plato_output, plato_utf8,
1796 "conversion of UTF8 to UTF8");
1797 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 memset(plato_output.data, '\0', plato_output.length);
1803 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 torture_assert_data_blob_equal(tctx, plato_output, plato_utf8,
1809 "conversion of UTF8 to UTF8");
1811 memset(plato_output.data, '\0', plato_output.length);
1812 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 torture_assert_errno_equal(tctx, EILSEQ, "conversion of UTF16 ancient greek to any DOS charset should fail EILSEQ");
1819 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");
1825 /* Allocate only enough space for a partial conversion */
1826 plato_output = data_blob_talloc(tctx, NULL, 9);
1827 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 torture_assert_errno_equal(tctx, E2BIG, "conversion of UTF16 ancient greek to UTF8 should fail, not enough space");
1833 torture_assert_int_equal(tctx, plato_output.length, 8,
1834 "conversion of UTF16 ancient greek to UTF8 should stop on multibyte boundary");
1836 plato_output = data_blob_talloc(tctx, NULL, 2);
1837 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 torture_assert_errno_equal(tctx, E2BIG, "conversion of UTF16 ancient greek to UTF8 should fail, not enough space");
1843 torture_assert_int_equal(tctx, plato_output.length, 0,
1844 "conversion of UTF16 ancient greek to UTF8 should stop on multibyte boundary");
1847 return true;
1852 static bool test_short_strings(struct torture_context *tctx)
1854 char zeros[6] = {0};
1855 char s[6] = {'s'};
1856 bool ok;
1857 char *out;
1858 size_t out_len;
1860 ok = convert_string_talloc(tctx,
1861 CH_UTF8, CH_UTF16LE,
1862 zeros, 0,
1863 &out, &out_len);
1864 torture_assert(tctx, ok, "{\"\", 0} to utf16 failed");
1865 torture_assert(tctx, out_len == 2, "{\"\", 0} length is two");
1866 torture_assert(tctx, out[0] == 0 && out[1] == 0, "{\"\", 0} utf16 is zero");
1867 TALLOC_FREE(out);
1869 ok = convert_string_talloc(tctx,
1870 CH_UTF8, CH_UTF16LE,
1871 zeros, 1,
1872 &out, &out_len);
1873 torture_assert(tctx, ok, "{\"\\0\", 1} to utf16 failed");
1874 torture_assert(tctx, out_len == 2, "{\"\\0\", 1} length is two");
1875 torture_assert(tctx, out[0] == 0 && out[1] == 0, "{\"\\0\", 1} utf16 is zero");
1876 TALLOC_FREE(out);
1878 ok = convert_string_talloc(tctx,
1879 CH_UTF8, CH_UTF16LE,
1880 zeros, 2,
1881 &out, &out_len);
1882 torture_assert(tctx, ok, "{\"\\0\\0\", 2} to utf16 failed");
1883 torture_assert(tctx, out_len == 4, "{\"\\0\\0\", 2} length is four");
1884 torture_assert(tctx, out[0] == 0 && out[1] == 0, "{\"\\0\\0\", 2} utf16 is zero");
1885 TALLOC_FREE(out);
1887 ok = convert_string_talloc(tctx,
1888 CH_UTF8, CH_UTF16LE,
1889 s, 0,
1890 &out, &out_len);
1891 torture_assert(tctx, ok, "{\"s\", 0} to utf16 failed");
1892 torture_assert(tctx, out_len == 2, "{\"s\", 0} length is two");
1893 torture_assert(tctx, out[0] == 0 && out[1] == 0,
1894 "{\"s\", 0} utf16 is zero");
1895 TALLOC_FREE(out);
1897 ok = convert_string_talloc(tctx,
1898 CH_UTF8, CH_UTF16LE,
1899 s, 1,
1900 &out, &out_len);
1901 torture_assert(tctx, ok, "{\"s\", 1} to utf16 failed");
1902 torture_assert(tctx, out_len == 2, "{\"s\", 1} length is two");
1903 torture_assert(tctx, out[0] == 's' && out[1] == 0,
1904 "{\"s\", 1} utf16 is s");
1905 TALLOC_FREE(out);
1907 ok = convert_string_talloc(tctx,
1908 CH_UTF8, CH_UTF16LE,
1909 s, 2,
1910 &out, &out_len);
1911 torture_assert(tctx, ok, "{\"s\\0\", 2} to utf16 failed");
1912 torture_assert(tctx, out_len == 4, "{\"s\\0\", 2} length is four");
1913 torture_assert(tctx, out[0] == 's' && out[1] == 0,
1914 "{\"s\\0\", 0} utf16 is s");
1915 TALLOC_FREE(out);
1918 /* going to utf8 */
1919 ok = convert_string_talloc(tctx,
1920 CH_UTF16LE, CH_UTF8,
1921 zeros, 0,
1922 &out, &out_len);
1923 torture_assert(tctx, ok, "{\"\", 0} to utf8 failed");
1924 torture_assert(tctx, out_len == 1, "{\"\", 0} length is one");
1925 torture_assert(tctx, out[0] == 0, "{\"\", 0} utf8[0] is zero");
1926 TALLOC_FREE(out);
1928 ok = convert_string_talloc(tctx,
1929 CH_UTF16LE, CH_UTF8,
1930 zeros, 2,
1931 &out, &out_len);
1932 torture_assert(tctx, ok, "{\"\\0\", 1} to utf8 failed");
1933 torture_assert(tctx, out_len == 1, "{\"\\0\", 1} length is one");
1934 torture_assert(tctx, out[0] == 0 && out[1] == 0,
1935 "{\"\\0\", 1} utf8 is zero");
1936 TALLOC_FREE(out);
1938 ok = convert_string_talloc(tctx,
1939 CH_UTF16LE, CH_UTF8,
1940 zeros, 4,
1941 &out, &out_len);
1942 torture_assert(tctx, ok, "{\"\\0\\0\\0\\0\", 4} to utf8 failed");
1943 torture_assert(tctx, out_len == 2, "{\"\\0\\0\\0\\0\", 4} length is two");
1944 torture_assert(tctx, out[0] == 0 && out[1] == 0,
1945 "{\"\\0\\0\\0\\0\", 4} utf8 is zero");
1946 TALLOC_FREE(out);
1948 ok = convert_string_talloc(tctx,
1949 CH_UTF16LE, CH_UTF8,
1950 s, 0,
1951 &out, &out_len);
1952 torture_assert(tctx, ok, "{\"s\", 0} to utf8 failed");
1953 torture_assert(tctx, out_len == 1, "{\"s\", 0} length is one");
1954 torture_assert(tctx, out[0] == 0, "{\"s\", 0} utf8 is zero");
1955 TALLOC_FREE(out);
1957 ok = convert_string_talloc(tctx,
1958 CH_UTF16LE, CH_UTF8,
1959 s, 2,
1960 &out, &out_len);
1961 torture_assert(tctx, ok, "{\"s\\0\", 2} to utf8 failed");
1962 torture_assert(tctx, out_len == 1, "{\"s\\0\", 2} length is one");
1963 torture_assert(tctx, out[0] == 's' && out[1] == 0,
1964 "{\"s\\0\", 2} utf8 is s");
1965 TALLOC_FREE(out);
1968 ok = convert_string_talloc(tctx,
1969 CH_UTF16LE, CH_UTF8,
1970 s, 4,
1971 &out, &out_len);
1972 torture_assert(tctx, ok, "{\"s\\0\\0\\0\", 4} utf8 failed");
1973 torture_assert(tctx, out_len == 2, "\"s\\0\\0\\0\", 4} utf8 length is two");
1974 torture_assert(tctx, out[0] == 's' && out[1] == 0,
1975 "{\"s\\0\\0\\0\", 4} utf8 is s");
1976 TALLOC_FREE(out);
1978 /* odd numbers of bytes from UTF-16 should fail */
1979 ok = convert_string_talloc(tctx,
1980 CH_UTF16LE, CH_UTF8,
1981 s, 1,
1982 &out, &out_len);
1983 torture_assert(tctx, ! ok, "{\"s\", 1} to utf8 should have failed");
1985 ok = convert_string_talloc(tctx,
1986 CH_UTF16LE, CH_UTF8,
1987 s, 3,
1988 &out, &out_len);
1989 torture_assert(tctx, ! ok, "{\"s\\0\\0\", 3} to utf8 should have failed");
1991 ok = convert_string_talloc(tctx,
1992 CH_UTF16LE, CH_UTF8,
1993 zeros, 1,
1994 &out, &out_len);
1995 torture_assert(tctx, ! ok,
1996 "{\"\\0\", 1} to utf8 should have failed");
1998 ok = convert_string_talloc(tctx,
1999 CH_UTF16LE, CH_UTF8,
2000 zeros, 5,
2001 &out, &out_len);
2002 torture_assert(tctx, ! ok,
2003 "{\"\\0\\0\\0\\0\", 5} to utf8 should have failed");
2005 return true;
2009 static bool test_plato_latin(struct torture_context *tctx)
2011 DATA_BLOB plato_latin_utf8 = base64_decode_data_blob(plato_latin_utf8_base64);
2012 DATA_BLOB plato_latin_utf16le = base64_decode_data_blob(plato_latin_utf16le_base64);
2013 DATA_BLOB plato_latin_output;
2015 talloc_steal(tctx, plato_latin_utf8.data);
2016 talloc_steal(tctx, plato_latin_utf16le.data);
2018 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 torture_assert_data_blob_equal(tctx, plato_latin_output, plato_latin_utf8, "conversion from UTF16 to UTF8 incorrect");
2025 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 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 torture_assert_data_blob_equal(tctx, plato_latin_output, plato_latin_utf16le, "conversion from UTF8 to UTF16LE incorrect");
2037 return true;
2040 static bool test_gd_case(struct torture_context *tctx)
2042 DATA_BLOB gd_utf8 = base64_decode_data_blob(gd_utf8_base64);
2043 char *gd_unix;
2044 size_t gd_size;
2045 char *gd_lower, *gd_upper;
2046 talloc_steal(tctx, gd_utf8.data);
2048 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");
2053 gd_lower = strlower_talloc(tctx, gd_unix);
2054 torture_assert(tctx, gd_lower, "failed to convert GD's name into lower case");
2055 gd_upper = strupper_talloc_n(tctx, gd_unix, gd_size);
2056 torture_assert(tctx, gd_lower, "failed to convert GD's name into upper case");
2058 torture_assert(tctx,
2059 strhasupper(gd_unix),
2060 "GD's name has an upper case character");
2061 torture_assert(tctx,
2062 strhaslower(gd_unix),
2063 "GD's name has an lower case character");
2064 torture_assert(tctx,
2065 strhasupper(gd_upper),
2066 "upper case name has an upper case character");
2067 torture_assert(tctx,
2068 strhaslower(gd_lower),
2069 "lower case name has an lower case character");
2070 torture_assert(tctx,
2071 strhasupper(gd_lower) == false,
2072 "lower case name has no upper case character");
2073 torture_assert(tctx,
2074 strhaslower(gd_upper) == false,
2075 "upper case name has no lower case character");
2077 torture_assert(tctx, strcasecmp_m(gd_unix,
2078 gd_upper) == 0,
2079 "case insensitive comparison orig/upper");
2080 torture_assert(tctx, strcasecmp_m(gd_unix,
2081 gd_lower) == 0,
2082 "case insensitive comparison orig/lower");
2083 torture_assert(tctx, strcasecmp_m(gd_upper,
2084 gd_lower) == 0,
2085 "case insensitive comparison upper/lower");
2087 /* This string isn't different in length upper/lower, but just check the first 5 chars */
2088 torture_assert(tctx, strncasecmp_m(gd_unix,
2089 gd_upper, 5) == 0,
2090 "case insensitive comparison orig/upper");
2091 torture_assert(tctx, strncasecmp_m(gd_unix,
2092 gd_lower, 5) == 0,
2093 "case insensitive comparison orig/lower");
2094 torture_assert(tctx, strncasecmp_m(gd_upper,
2095 gd_lower, 5) == 0,
2096 "case insensitive comparison upper/lower");
2097 return true;
2100 static bool test_plato_case(struct torture_context *tctx)
2102 DATA_BLOB plato_utf8 = base64_decode_data_blob(plato_utf8_base64);
2103 char *plato_unix;
2104 size_t plato_length;
2105 char *plato_lower, *plato_upper;
2106 talloc_steal(tctx, plato_utf8.data);
2108 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");
2113 torture_assert(tctx,
2114 strhasupper(plato_unix),
2115 "PLATO's apology has an upper case character");
2116 torture_assert(tctx,
2117 strhaslower(plato_unix),
2118 "PLATO's apology has an lower case character");
2119 plato_lower = strlower_talloc(tctx, plato_unix);
2120 torture_assert(tctx, plato_lower, "failed to convert PLATO's apology into lower case");
2121 plato_upper = strupper_talloc_n(tctx, plato_unix, plato_utf8.length);
2122 torture_assert(tctx, plato_lower, "failed to convert PLATO's apology into upper case");
2124 torture_assert(tctx,
2125 strhasupper(plato_upper),
2126 "upper case string has an upper case character");
2127 torture_assert(tctx,
2128 strhaslower(plato_lower),
2129 "lower case string has an lower case character");
2130 torture_assert(tctx,
2131 strhasupper(plato_lower) == false,
2132 "lower case string has no upper case character");
2133 torture_assert(tctx,
2134 strhaslower(plato_upper) == false,
2135 "upper case string has no lower case character");
2137 torture_assert(tctx, strcasecmp_m(plato_unix,
2138 plato_upper) == 0,
2139 "case insensitive comparison orig/upper");
2140 torture_assert(tctx, strcasecmp_m(plato_unix,
2141 plato_lower) == 0,
2142 "case insensitive comparison orig/lower");
2143 torture_assert(tctx, strcasecmp_m(plato_upper,
2144 plato_lower) == 0,
2145 "case insensitive comparison upper/lower");
2146 return true;
2149 struct torture_suite *torture_local_convert_string_handle(TALLOC_CTX *mem_ctx)
2151 struct torture_suite *suite = torture_suite_create(mem_ctx, "convert_string_handle");
2152 torture_suite_add_simple_test(suite, "cp850 high points", test_cp850_high_points);
2154 torture_suite_add_simple_test(suite, "gd_ascii", test_gd_ascii_handle);
2155 torture_suite_add_simple_test(suite, "gd_minus_1", test_gd_minus_1_handle);
2156 torture_suite_add_simple_test(suite, "gd_iso8859_cp850", test_gd_iso8859_cp850_handle);
2157 torture_suite_add_simple_test(suite, "plato_english_iso8859_cp850", test_plato_english_iso8859_cp850_handle);
2158 torture_suite_add_simple_test(suite, "plato_english_minus_1", test_plato_english_minus_1_handle);
2159 torture_suite_add_simple_test(suite, "plato_cp850_utf8", test_plato_cp850_utf8_handle);
2160 torture_suite_add_simple_test(suite, "plato_minus_1", test_plato_minus_1_handle);
2161 torture_suite_add_simple_test(suite, "plato_latin_cp850_utf8", test_plato_latin_cp850_utf8_handle);
2162 torture_suite_add_simple_test(suite, "utf8-nfc-to-nfd", test_utf8_nfc_to_nfd);
2163 torture_suite_add_simple_test(suite, "utf8-nfc-to-nfd-overflow", test_utf8_nfc_to_nfd_overflow);
2164 torture_suite_add_simple_test(suite, "utf8-nfd-to-nfc", test_utf8_nfd_to_nfc);
2165 return suite;
2168 struct torture_suite *torture_local_string_case_handle(TALLOC_CTX *mem_ctx)
2170 struct torture_suite *suite = torture_suite_create(mem_ctx, "string_case_handle");
2172 torture_suite_add_simple_test(suite, "gd_case_utf8", test_gd_case_utf8_handle);
2173 torture_suite_add_simple_test(suite, "gd_case_cp850", test_gd_case_cp850_handle);
2174 torture_suite_add_simple_test(suite, "plato_case_utf8", test_plato_case_utf8_handle);
2175 return suite;
2178 struct torture_suite *torture_local_convert_string(TALLOC_CTX *mem_ctx)
2180 struct torture_suite *suite = torture_suite_create(mem_ctx, "convert_string");
2182 torture_suite_add_simple_test(suite, "short_strings", test_short_strings);
2183 torture_suite_add_simple_test(suite, "gd", test_gd);
2184 torture_suite_add_simple_test(suite, "plato", test_plato);
2185 torture_suite_add_simple_test(suite, "plato_latin", test_plato_latin);
2186 return suite;
2189 struct torture_suite *torture_local_string_case(TALLOC_CTX *mem_ctx)
2191 struct torture_suite *suite = torture_suite_create(mem_ctx, "string_case_handle");
2193 torture_suite_add_simple_test(suite, "gd_case", test_gd_case);
2194 torture_suite_add_simple_test(suite, "plato_case", test_plato_case);
2195 return suite;