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/>.
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"
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"
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=";
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
);
116 DATA_BLOB cp850_return
;
118 iconv_handle
= get_iconv_testing_handle(tctx
, "CP850", "UTF8",
119 lpcfg_parm_bool(tctx
->lp_ctx
,
122 "use_builtin_handlers",
125 torture_assert(tctx
, iconv_handle
, "creating iconv handle");
128 convert_string_talloc_handle(tctx
, iconv_handle
,
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");
138 memcmp(utf8
.data
, utf8_high_points
, utf8
.length
) == 0,
139 "cp850 converted to utf8 matches expected value");
142 convert_string_talloc_handle(tctx
, iconv_handle
,
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");
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
);
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
,
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
,
183 gd_utf8
.data
, gd_utf8
.length
,
184 (void *)gd_output
.data
, 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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
344 "checking strlen_m_ext of conversion from (dos charset) ISO-8859-1 to UTF8");
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
);
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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");
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
);
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
,
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
,
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
,
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
,
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
,
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");
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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");
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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");
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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");
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
1170 plato_output2
.length
,
1171 "checking strlen_m_ext of conversion of UTF8 to UTF8");
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
,
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
,
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
,
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
,
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");
1246 static bool test_utf8_nfc_to_nfd_overflow(struct torture_context
*tctx
)
1249 DATA_BLOB utf8_nfc_blob
;
1250 DATA_BLOB utf8_nfd_blob
;
1254 const char *src
= NULL
;
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
,
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
,
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().
1283 dst
= (char *)blob
.data
;
1285 nconv
= smb_iconv(ic
,
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
,
1297 dst
= (char *)blob
.data
;
1299 nconv
= smb_iconv(ic
,
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
,
1311 dst
= (char *)blob
.data
;
1313 nconv
= smb_iconv(ic
,
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
,
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
;
1328 nconv
= smb_iconv(ic
,
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
,
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
;
1347 nconv
= smb_iconv(ic
,
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
,
1359 "Conversion failed\n");
1365 static bool test_utf8_nfc_to_nfd(struct torture_context
*tctx
)
1368 DATA_BLOB utf8_nfc_blob
;
1369 DATA_BLOB utf8_nfd_blob
;
1372 const char *src
= NULL
;
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
,
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
,
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
,
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
,
1410 "Conversion failed\n");
1416 static bool test_utf8_nfd_to_nfc(struct torture_context
*tctx
)
1419 DATA_BLOB utf8_nfc_blob
;
1420 DATA_BLOB utf8_nfd_blob
;
1423 const char *src
= NULL
;
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
,
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
,
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
,
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
,
1461 "Conversion failed\n");
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
,
1510 "case insensitive comparison orig/upper");
1511 torture_assert(tctx
, strcasecmp_m_handle(iconv_handle
, (const char *)gd_utf8
.data
,
1513 "case insensitive comparison orig/lower");
1514 torture_assert(tctx
, strcasecmp_m_handle(iconv_handle
, gd_upper
,
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
);
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
,
1579 "case insensitive comparison orig/upper");
1580 torture_assert(tctx
, strcasecmp_m_handle(iconv_handle
, (const char *)gd_cp850
.data
,
1582 "case insensitive comparison orig/lower");
1583 torture_assert(tctx
, strcasecmp_m_handle(iconv_handle
, gd_upper
,
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
);
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
,
1642 "case insensitive comparison orig/upper");
1643 torture_assert(tctx
, strcasecmp_m_handle(iconv_handle
, (const char *)plato_utf8
.data
,
1645 "case insensitive comparison orig/lower");
1646 torture_assert(tctx
, strcasecmp_m_handle(iconv_handle
, plato_upper
,
1648 "case insensitive comparison upper/lower");
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
;
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
,
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
,
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");
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
,
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");
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
,
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
,
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
,
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");
1852 static bool test_short_strings(struct torture_context
*tctx
)
1854 char zeros
[6] = {0};
1860 ok
= convert_string_talloc(tctx
,
1861 CH_UTF8
, CH_UTF16LE
,
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");
1869 ok
= convert_string_talloc(tctx
,
1870 CH_UTF8
, CH_UTF16LE
,
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");
1878 ok
= convert_string_talloc(tctx
,
1879 CH_UTF8
, CH_UTF16LE
,
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");
1887 ok
= convert_string_talloc(tctx
,
1888 CH_UTF8
, CH_UTF16LE
,
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");
1897 ok
= convert_string_talloc(tctx
,
1898 CH_UTF8
, CH_UTF16LE
,
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");
1907 ok
= convert_string_talloc(tctx
,
1908 CH_UTF8
, CH_UTF16LE
,
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");
1919 ok
= convert_string_talloc(tctx
,
1920 CH_UTF16LE
, CH_UTF8
,
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");
1928 ok
= convert_string_talloc(tctx
,
1929 CH_UTF16LE
, CH_UTF8
,
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");
1938 ok
= convert_string_talloc(tctx
,
1939 CH_UTF16LE
, CH_UTF8
,
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");
1948 ok
= convert_string_talloc(tctx
,
1949 CH_UTF16LE
, CH_UTF8
,
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");
1957 ok
= convert_string_talloc(tctx
,
1958 CH_UTF16LE
, CH_UTF8
,
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");
1968 ok
= convert_string_talloc(tctx
,
1969 CH_UTF16LE
, CH_UTF8
,
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");
1978 /* odd numbers of bytes from UTF-16 should fail */
1979 ok
= convert_string_talloc(tctx
,
1980 CH_UTF16LE
, CH_UTF8
,
1983 torture_assert(tctx
, ! ok
, "{\"s\", 1} to utf8 should have failed");
1985 ok
= convert_string_talloc(tctx
,
1986 CH_UTF16LE
, CH_UTF8
,
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
,
1995 torture_assert(tctx
, ! ok
,
1996 "{\"\\0\", 1} to utf8 should have failed");
1998 ok
= convert_string_talloc(tctx
,
1999 CH_UTF16LE
, CH_UTF8
,
2002 torture_assert(tctx
, ! ok
,
2003 "{\"\\0\\0\\0\\0\", 5} to utf8 should have failed");
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");
2040 static bool test_gd_case(struct torture_context
*tctx
)
2042 DATA_BLOB gd_utf8
= base64_decode_data_blob(gd_utf8_base64
);
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
,
2079 "case insensitive comparison orig/upper");
2080 torture_assert(tctx
, strcasecmp_m(gd_unix
,
2082 "case insensitive comparison orig/lower");
2083 torture_assert(tctx
, strcasecmp_m(gd_upper
,
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
,
2090 "case insensitive comparison orig/upper");
2091 torture_assert(tctx
, strncasecmp_m(gd_unix
,
2093 "case insensitive comparison orig/lower");
2094 torture_assert(tctx
, strncasecmp_m(gd_upper
,
2096 "case insensitive comparison upper/lower");
2100 static bool test_plato_case(struct torture_context
*tctx
)
2102 DATA_BLOB plato_utf8
= base64_decode_data_blob(plato_utf8_base64
);
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
,
2139 "case insensitive comparison orig/upper");
2140 torture_assert(tctx
, strcasecmp_m(plato_unix
,
2142 "case insensitive comparison orig/lower");
2143 torture_assert(tctx
, strcasecmp_m(plato_upper
,
2145 "case insensitive comparison upper/lower");
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
);
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
);
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
);
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
);