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"
25 /* The text below is in ancient and a latin charset transliteration of
26 * greek, and an english translation. It from Apology by Plato and sourced from
27 * http://en.wikipedia.org/w/index.php?title=Ancient_Greek&oldid=421361065#Example_text
30 const char *plato_english_ascii =
31 "What you, men of Athens, have learned from my accusers, I do not"
32 " know: but I, for my part, nearly forgot who I was thanks to them since"
33 " they spoke so persuasively. And yet, of the truth, they have spoken,"
34 " one might say, nothing at all.";
36 const char *plato_english_utf16le_base64 =
37 "VwBoAGEAdAAgAHkAbwB1ACwAIABtAGUAbgAgAG8AZgAgAEEAdABoAGUAbgBzACwAIABoAGEAdgBl"
38 "ACAAbABlAGEAcgBuAGUAZAAgAGYAcgBvAG0AIABtAHkAIABhAGMAYwB1AHMAZQByAHMALAAgAEkA"
39 "IABkAG8AIABuAG8AdAAgAGsAbgBvAHcAOgAgAGIAdQB0ACAASQAsACAAZgBvAHIAIABtAHkAIABw"
40 "AGEAcgB0ACwAIABuAGUAYQByAGwAeQAgAGYAbwByAGcAbwB0ACAAdwBoAG8AIABJACAAdwBhAHMA"
41 "IAB0AGgAYQBuAGsAcwAgAHQAbwAgAHQAaABlAG0AIABzAGkAbgBjAGUAIAB0AGgAZQB5ACAAcwBw"
42 "AG8AawBlACAAcwBvACAAcABlAHIAcwB1AGEAcwBpAHYAZQBsAHkALgAgAEEAbgBkACAAeQBlAHQA"
43 "LAAgAG8AZgAgAHQAaABlACAAdAByAHUAdABoACwAIAB0AGgAZQB5ACAAaABhAHYAZQAgAHMAcABv"
44 "AGsAZQBuACwAIABvAG4AZQAgAG0AaQBnAGgAdAAgAHMAYQB5ACwAIABuAG8AdABoAGkAbgBnACAA"
45 "YQB0ACAAYQBsAGwALgA=";
47 static const char *plato_utf8_base64 =
48 "4b2Nz4TOuSDOvOG9ss69IOG9kc68zrXhv5bPgiwg4b2mIOG8hM69zrTPgc61z4IgzobOuM63zr3O"
49 "seG/ls6/zrksIM+AzrXPgM+Mzr3OuM6xz4TOtSDhvZHPgOG9uCDPhOG/ts69IOG8kM684b+2zr0g"
50 "zrrOsc+EzrfOs8+Mz4HPic69LCDOv+G9kM66IM6/4by2zrTOsTog4byQzrPhvbwgzrQnIM6/4b2W"
51 "zr0gzrrOseG9tiDOseG9kM+E4b24z4Ig4b2Rz4AnIM6x4b2Qz4Thv7bOvSDhvYDOu86vzrPOv8+F"
52 "IOG8kM68zrHPhc+Ezr/hv6Yg4byQz4DOtc67zrHOuM+MzrzOt869LCDOv+G9lc+Ez4kgz4DOuc64"
53 "zrHOveG/ts+CIOG8lM67zrXOs86/zr0uIM6azrHOr8+Ezr/OuSDhvIDOu863zrjOrc+CIM6zzrUg"
54 "4b2hz4Ig4byUz4DOv8+CIM614bywz4DOteG/ls69IM6/4b2QzrThvbLOvSDOteG8sM+Bzq7Ous6x"
57 static const char *plato_utf16le_base64 =
58 "TR/EA7kDIAC8A3IfvQMgAFEfvAO1A9YfwgMsACAAZh8gAAQfvQO0A8EDtQPCAyAAhgO4A7cDvQOx"
59 "A9YfvwO5AywAIADAA7UDwAPMA70DuAOxA8QDtQMgAFEfwAN4HyAAxAP2H70DIAAQH7wD9h+9AyAA"
60 "ugOxA8QDtwOzA8wDwQPJA70DLAAgAL8DUB+6AyAAvwM2H7QDsQM6ACAAEB+zA3wfIAC0AycAIAC/"
61 "A1YfvQMgALoDsQN2HyAAsQNQH8QDeB/CAyAAUR/AAycAIACxA1AfxAP2H70DIABAH7sDrwOzA78D"
62 "xQMgABAfvAOxA8UDxAO/A+YfIAAQH8ADtQO7A7EDuAPMA7wDtwO9AywAIAC/A1UfxAPJAyAAwAO5"
63 "A7gDsQO9A/YfwgMgABQfuwO1A7MDvwO9Ay4AIACaA7EDrwPEA78DuQMgAAAfuwO3A7gDrQPCAyAA"
64 "swO1AyAAYR/CAyAAFB/AA78DwgMgALUDMB/AA7UD1h+9AyAAvwNQH7QDch+9AyAAtQMwH8EDrgO6"
67 static const char *plato_latin_utf8_base64 =
68 "SMOzdGkgbcOobiBodW1lw65zLCDDtCDDoW5kcmVzIEF0aMSTbmHDrm9pLCBwZXDDs250aGF0ZSBo"
69 "dXDDsiB0w7RuIGVtw7RuIGthdMSTZ8OzcsWNbiwgb3VrIG/DrmRhOiBlZ+G5kSBkJyBvw7tuIGth"
70 "w6wgYXV0w7JzIGh1cCcgYXV0xY1uIG9sw61nb3UgZW1hdXRvw7sgZXBlbGF0aMOzbcSTbiwgaG/D"
71 "unTFjSBwaXRoYW7DtHMgw6lsZWdvbi4gS2HDrXRvaSBhbMSTdGjDqXMgZ2UgaMWNcyDDqXBvcyBl"
72 "aXBlw65uIG91ZMOobiBlaXLhuJdrYXNpbi4=";
74 static const char *plato_latin_utf16le_base64 =
75 "SADzAHQAaQAgAG0A6ABuACAAaAB1AG0AZQDuAHMALAAgAPQAIADhAG4AZAByAGUAcwAgAEEAdABo"
76 "ABMBbgBhAO4AbwBpACwAIABwAGUAcADzAG4AdABoAGEAdABlACAAaAB1AHAA8gAgAHQA9ABuACAA"
77 "ZQBtAPQAbgAgAGsAYQB0ABMBZwDzAHIATQFuACwAIABvAHUAawAgAG8A7gBkAGEAOgAgAGUAZwBR"
78 "HiAAZAAnACAAbwD7AG4AIABrAGEA7AAgAGEAdQB0APIAcwAgAGgAdQBwACcAIABhAHUAdABNAW4A"
79 "IABvAGwA7QBnAG8AdQAgAGUAbQBhAHUAdABvAPsAIABlAHAAZQBsAGEAdABoAPMAbQATAW4ALAAg"
80 "AGgAbwD6AHQATQEgAHAAaQB0AGgAYQBuAPQAcwAgAOkAbABlAGcAbwBuAC4AIABLAGEA7QB0AG8A"
81 "aQAgAGEAbAATAXQAaADpAHMAIABnAGUAIABoAE0BcwAgAOkAcABvAHMAIABlAGkAcABlAO4AbgAg"
82 "AG8AdQBkAOgAbgAgAGUAaQByABceawBhAHMAaQBuAC4A";
84 static const char *gd_utf8_base64 = "R8O8bnRoZXIgRGVzY2huZXI=";
85 static const char *gd_utf8_upper_base64 = "R8OcTlRIRVIgREVTQ0hORVI=";
86 static const char *gd_utf8_lower_base64 = "Z8O8bnRoZXIgZGVzY2huZXI=";
87 static const char *gd_cp850_base64 = "R4FudGhlciBEZXNjaG5lcg==";
88 static const char *gd_cp850_upper_base64 = "R5pOVEhFUiBERVNDSE5FUg==";
89 static const char *gd_cp850_lower_base64 = "Z4FudGhlciBkZXNjaG5lcg==";
90 static const char *gd_iso8859_1_base64 = "R/xudGhlciBEZXNjaG5lcg==";
91 static const char *gd_utf16le_base64 = "RwD8AG4AdABoAGUAcgAgAEQAZQBzAGMAaABuAGUAcgA=";
93 static bool test_gd_iso8859_cp850_handle(struct torture_context *tctx)
95 struct smb_iconv_handle *iconv_handle;
96 DATA_BLOB gd_utf8 = base64_decode_data_blob(gd_utf8_base64);
97 DATA_BLOB gd_cp850 = base64_decode_data_blob(gd_cp850_base64);
98 DATA_BLOB gd_iso8859_1 = base64_decode_data_blob(gd_iso8859_1_base64);
99 DATA_BLOB gd_utf16le = base64_decode_data_blob(gd_utf16le_base64);
101 DATA_BLOB gd_output2;
103 talloc_steal(tctx, gd_utf8.data);
104 talloc_steal(tctx, gd_cp850.data);
105 talloc_steal(tctx, gd_iso8859_1.data);
106 talloc_steal(tctx, gd_utf16le.data);
108 iconv_handle = get_iconv_testing_handle(tctx, "ISO8859-1", "CP850");
109 torture_assert(tctx, iconv_handle, "getting iconv handle");
111 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
113 gd_utf8.data, gd_utf8.length,
114 (void *)&gd_output.data, &gd_output.length),
115 "conversion from UTF8 to (dos charset) ISO8859-1");
116 torture_assert_data_blob_equal(tctx, gd_output, gd_iso8859_1, "conversion from UTF8 to (dos charset) ISO8859-1 incorrect");
118 torture_assert(tctx, convert_string_error_handle(iconv_handle,
120 gd_utf8.data, gd_utf8.length,
121 (void *)gd_output.data, gd_output.length,
123 "conversion from UTF8 to (dos charset) ISO8859-1");
124 torture_assert_data_blob_equal(tctx, gd_output, gd_iso8859_1, "conversion from UTF8 to (dos charset) ISO8859-1 incorrect");
126 /* Short output handling confirmation */
127 gd_output.length = 1;
128 torture_assert(tctx, convert_string_error_handle(iconv_handle,
130 gd_utf8.data, gd_utf8.length,
131 (void *)gd_output.data, gd_output.length,
132 &gd_output.length) == false,
133 "conversion from UTF8 to (dos charset) ISO8859-1 should fail due to too short");
134 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to (dos charset) ISO8859-1 should fail E2BIG");
135 torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
136 torture_assert_data_blob_equal(tctx, gd_output, data_blob_string_const("G"), "conversion from UTF8 to (dos charset) ISO8859-1 incorrect");
138 /* Short output handling confirmation */
139 gd_output.length = 2;
140 torture_assert(tctx, convert_string_error_handle(iconv_handle,
142 gd_utf8.data, gd_utf8.length,
143 (void *)gd_output.data, gd_output.length,
144 &gd_output.length) == false,
145 "conversion from UTF8 to (dos charset) ISO8859-1 should fail due to too short");
146 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to (dos charset) ISO8859-1 should fail E2BIG");
147 torture_assert_int_equal(tctx, gd_output.length, 2, "Should only get 2 char of output");
149 /* Short input handling confirmation */
150 gd_output.length = gd_iso8859_1.length;
151 torture_assert(tctx, convert_string_error_handle(iconv_handle,
154 (void *)gd_output.data, gd_output.length,
155 &gd_output.length) == false,
156 "conversion from UTF8 to (dos charset) ISO8859-1 should fail due to too short");
157 torture_assert_errno_equal(tctx, EILSEQ, "conversion from short UTF8 to (dos charset) ISO8859-1 should fail EINVAL");
158 torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
160 /* Short output handling confirmation */
161 gd_output.length = 1;
162 torture_assert(tctx, convert_string_error_handle(iconv_handle,
164 gd_utf16le.data, gd_utf16le.length,
165 (void *)gd_output.data, gd_output.length,
166 &gd_output.length) == false,
167 "conversion from UTF16 to UTF8 should fail due to too short");
168 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16 to (utf8 charset) ISO8859-1 should fail E2BIG");
169 torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
170 torture_assert_data_blob_equal(tctx, gd_output, data_blob_string_const("G"), "conversion from UTF16 to UTF8 incorrect");
172 /* Short output handling confirmation */
173 gd_output.length = 3;
174 torture_assert(tctx, convert_string_error_handle(iconv_handle,
176 gd_utf16le.data, gd_utf16le.length,
177 (void *)gd_output.data, gd_output.length,
178 &gd_output.length) == false,
179 "conversion from UTF16 to UTF8 should fail due to too short");
180 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16 to (utf8 charset) ISO8859-1 should fail E2BIG");
181 torture_assert_int_equal(tctx, gd_output.length, 3, "Should get 3 bytes output for UTF8");
183 /* Short input handling confirmation */
184 gd_output.length = gd_utf8.length;
185 torture_assert(tctx, convert_string_error_handle(iconv_handle,
188 (void *)gd_output.data, gd_output.length,
189 &gd_output.length) == false,
190 "conversion from UTF16 to UTF8 should fail due to too short");
191 torture_assert_errno_equal(tctx, EINVAL, "conversion from short UTF16 to UTF8 should fail EINVAL");
192 torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
194 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
196 gd_utf8.data, gd_utf8.length,
197 (void *)&gd_output.data, &gd_output.length),
198 "conversion from UTF8 to (unix charset) CP850");
199 torture_assert_data_blob_equal(tctx, gd_output, gd_cp850, "conversion from UTF8 to (unix charset) CP850 incorrect");
201 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
203 gd_utf8.data, gd_utf8.length,
204 (void *)&gd_output.data, &gd_output.length),
205 "conversion from UTF8 to UTF8");
206 torture_assert_data_blob_equal(tctx, gd_output, gd_utf8, "conversion from UTF8 to UTF8 incorrect");
208 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
210 gd_utf16le.data, gd_utf16le.length,
211 (void *)&gd_output.data, &gd_output.length),
212 "conversion from UTF16LE to (dos charset) ISO8859-1");
213 torture_assert_data_blob_equal(tctx, gd_output, gd_iso8859_1, "conversion from UTF16LE to (dos charset) ISO8859-1 incorrect");
215 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
217 gd_output.data, gd_output.length,
218 (void *)&gd_output2.data, &gd_output2.length),
219 "round trip conversion from (dos charset) ISO8859-1 back to UTF16LE");
220 torture_assert_data_blob_equal(tctx, gd_output2, gd_utf16le, "round trip conversion from (dos charset) ISO8859-1 back to UTF16LE");
222 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
224 gd_utf16le.data, gd_utf16le.length,
225 (void *)&gd_output.data, &gd_output.length),
226 "conversion from UTF16LE to (unix charset) CP850");
227 torture_assert_data_blob_equal(tctx, gd_output, gd_cp850, "conversion from UTF16LE to (unix charset) CP850 incorrect");
229 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
231 gd_utf16le.data, gd_utf16le.length,
232 (void *)&gd_output.data, &gd_output.length),
233 "conversion from UTF16LE to UTF8");
234 torture_assert_data_blob_equal(tctx, gd_output, gd_utf8, "conversion from UTF16LE to UTF8 incorrect");
236 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
238 gd_iso8859_1.data, gd_iso8859_1.length,
239 (void *)&gd_output.data, &gd_output.length),
240 "conversion from (dos charset) ISO8859-1 to (dos charset) ISO8859-1");
241 torture_assert_data_blob_equal(tctx, gd_output, gd_iso8859_1, "conversion from UTF16LE to (dos charset) ISO8859-1 incorrect");
243 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
245 gd_iso8859_1.data, gd_iso8859_1.length,
246 (void *)&gd_output.data, &gd_output.length),
247 "conversion from (dos charset) ISO8859-1 to (unix charset) CP850");
248 torture_assert_data_blob_equal(tctx, gd_output, gd_cp850, "conversion from UTF16LE to (unix charset) CP850 incorrect");
250 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
252 gd_iso8859_1.data, gd_iso8859_1.length,
253 (void *)&gd_output.data, &gd_output.length),
254 "conversion from (dos charset) ISO8859-1 to UTF8");
255 torture_assert_data_blob_equal(tctx, gd_output, gd_utf8, "conversion from UTF16LE to UTF8 incorrect");
257 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
259 gd_iso8859_1.data, gd_iso8859_1.length,
260 (void *)&gd_output.data, &gd_output.length),
261 "conversion from (dos charset) ISO8859-1 to UTF16LE");
262 torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le, "conversion from (dos charset) ISO8859-1 to UTF16LE");
263 torture_assert_int_equal(tctx,
264 strlen_m_ext_handle(iconv_handle,
265 (const char *)gd_iso8859_1.data,
267 gd_output.length / 2,
268 "checking strlen_m_ext of round trip conversion of UTF16 latin charset greek to UTF8 and back again");
270 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
272 gd_iso8859_1.data, gd_iso8859_1.length,
273 (void *)&gd_output.data, &gd_output.length),
274 "conversion from (dos charset) ISO8859-1 to UTF8");
275 torture_assert_data_blob_equal(tctx, gd_output, gd_utf8, "conversion from (dos charset) ISO8859-1 to UTF8");
276 torture_assert_int_equal(tctx,
277 strlen_m_ext_handle(iconv_handle,
278 (const char *)gd_iso8859_1.data,
281 "checking strlen_m_ext of conversion from (dos charset) ISO8859-1 to UTF8");
285 static bool test_gd_minus_1_handle(struct torture_context *tctx)
287 struct smb_iconv_handle *iconv_handle;
288 DATA_BLOB gd_utf8 = base64_decode_data_blob(gd_utf8_base64);
289 DATA_BLOB gd_cp850 = base64_decode_data_blob(gd_cp850_base64);
290 DATA_BLOB gd_utf16le = base64_decode_data_blob(gd_utf16le_base64);
292 DATA_BLOB gd_utf8_terminated;
293 DATA_BLOB gd_cp850_terminated;
294 DATA_BLOB gd_utf16le_terminated;
296 talloc_steal(tctx, gd_utf8.data);
297 talloc_steal(tctx, gd_cp850.data);
298 talloc_steal(tctx, gd_utf16le.data);
300 iconv_handle = get_iconv_testing_handle(tctx, "CP850", "CP850");
301 torture_assert(tctx, iconv_handle, "getting iconv handle");
303 gd_utf8_terminated = data_blob_talloc(tctx, NULL, gd_utf8.length + 1);
304 memcpy(gd_utf8_terminated.data, gd_utf8.data, gd_utf8.length);
305 gd_utf8_terminated.data[gd_utf8.length] = '\0';
307 gd_cp850_terminated = data_blob_talloc(tctx, NULL, gd_cp850.length + 1);
308 memcpy(gd_cp850_terminated.data, gd_cp850.data, gd_cp850.length);
309 gd_cp850_terminated.data[gd_cp850.length] = '\0';
311 gd_utf16le_terminated = data_blob_talloc(tctx, NULL, gd_utf16le.length + 2);
312 memcpy(gd_utf16le_terminated.data, gd_utf16le.data, gd_utf16le.length);
313 gd_utf16le_terminated.data[gd_utf16le.length] = '\0';
314 gd_utf16le_terminated.data[gd_utf16le.length + 1] = '\0';
316 gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
318 torture_assert(tctx, convert_string_error_handle(iconv_handle,
320 gd_utf8_terminated.data, -1,
321 (void *)gd_output.data, gd_output.length, &gd_output.length),
322 "conversion from UTF8 to UTF16LE null terminated");
323 torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated");
325 gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
326 torture_assert(tctx, convert_string_error_handle(iconv_handle,
328 gd_utf8_terminated.data, -1,
329 (void *)gd_output.data, gd_utf16le.length, &gd_output.length) == false,
330 "conversion from UTF8 to UTF16LE null terminated should fail");
331 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
332 torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le, "conversion from UTF8 to UTF16LE null terminated");
334 gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
335 torture_assert(tctx, convert_string_error_handle(iconv_handle,
337 gd_utf8_terminated.data, -1,
338 (void *)gd_output.data, gd_utf16le.length - 1, &gd_output.length) == false,
339 "conversion from UTF8 to UTF16LE null terminated should fail");
340 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
342 gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
343 torture_assert(tctx, convert_string_error_handle(iconv_handle,
345 gd_utf8_terminated.data, -1,
346 (void *)gd_output.data, gd_utf16le.length - 2, &gd_output.length) == false,
347 "conversion from UTF8 to UTF16LE null terminated should fail");
348 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
350 gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10);
351 torture_assert(tctx, convert_string_error_handle(iconv_handle,
353 gd_utf16le_terminated.data, -1,
354 (void *)gd_output.data, gd_output.length, &gd_output.length),
355 "conversion from UTF16LE to UTF8 null terminated");
356 torture_assert_data_blob_equal(tctx, gd_output, gd_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated");
358 gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10);
360 torture_assert(tctx, convert_string_error_handle(iconv_handle,
362 gd_utf16le_terminated.data, -1,
363 (void *)gd_output.data, gd_utf8.length, &gd_output.length) == false,
364 "conversion from UTF16LE to UTF8 null terminated should fail");
365 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
366 torture_assert_data_blob_equal(tctx, gd_output, gd_utf8, "conversion from UTF16LE to UTF8 null terminated");
368 gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10);
370 torture_assert(tctx, convert_string_error_handle(iconv_handle,
372 gd_utf16le_terminated.data, -1,
373 (void *)gd_output.data, gd_utf8.length - 1, &gd_output.length) == false,
374 "conversion from UTF16LE to UTF8 null terminated should fail");
375 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
377 gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10);
379 torture_assert(tctx, convert_string_error_handle(iconv_handle,
381 gd_utf16le_terminated.data, -1,
382 (void *)gd_output.data, gd_utf8.length - 2, &gd_output.length) == false,
383 "conversion from UTF16LE to UTF8 null terminated should fail");
384 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
386 gd_output = data_blob_talloc(tctx, NULL, gd_cp850.length + 10);
388 torture_assert(tctx, convert_string_error_handle(iconv_handle,
390 gd_utf16le_terminated.data, -1,
391 (void *)gd_output.data, gd_output.length, &gd_output.length),
392 "conversion from UTF16LE to CP850 (dos) null terminated");
393 torture_assert_data_blob_equal(tctx, gd_output, gd_cp850_terminated, "conversion from UTF16LE to CP850 (dos) null terminated");
395 /* Now null terminate the string early, the confirm we don't skip the NULL and convert any further */
396 gd_utf8_terminated.data[3] = '\0';
397 gd_utf8_terminated.length = 4; /* used for the comparison only */
399 gd_cp850_terminated.data[2] = '\0';
400 gd_cp850_terminated.length = 3; /* used for the comparison only */
402 gd_utf16le_terminated.data[4] = '\0';
403 gd_utf16le_terminated.data[5] = '\0';
404 gd_utf16le_terminated.length = 6; /* used for the comparison only */
406 gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
408 torture_assert(tctx, convert_string_error_handle(iconv_handle,
410 gd_utf8_terminated.data, -1,
411 (void *)gd_output.data, gd_output.length, &gd_output.length),
412 "conversion from UTF8 to UTF16LE null terminated");
413 torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated early");
415 gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10);
417 torture_assert(tctx, convert_string_error_handle(iconv_handle,
419 gd_utf16le_terminated.data, -1,
420 (void *)gd_output.data, gd_output.length, &gd_output.length),
421 "conversion from UTF16LE to UTF8 null terminated");
422 torture_assert_data_blob_equal(tctx, gd_output, gd_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated early");
424 gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
426 torture_assert(tctx, convert_string_error_handle(iconv_handle,
428 gd_cp850_terminated.data, -1,
429 (void *)gd_output.data, gd_output.length, &gd_output.length),
430 "conversion from CP850 to UTF16LE null terminated");
431 torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated early");
433 gd_output = data_blob_talloc(tctx, NULL, gd_cp850.length + 10);
435 torture_assert(tctx, convert_string_error_handle(iconv_handle,
437 gd_utf16le_terminated.data, -1,
438 (void *)gd_output.data, gd_output.length, &gd_output.length),
439 "conversion from UTF16LE to UTF8 null terminated");
440 torture_assert_data_blob_equal(tctx, gd_output, gd_cp850_terminated, "conversion from UTF16LE to UTF8 null terminated early");
442 /* Now null terminate the string particularly early, the confirm we don't skip the NULL and convert any further */
443 gd_utf8_terminated.data[1] = '\0';
444 gd_utf8_terminated.length = 2; /* used for the comparison only */
446 gd_utf16le_terminated.data[2] = '\0';
447 gd_utf16le_terminated.data[3] = '\0';
448 gd_utf16le_terminated.length = 4; /* used for the comparison only */
450 gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
452 torture_assert(tctx, convert_string_error_handle(iconv_handle, CH_UTF8, CH_UTF16LE,
453 gd_utf8_terminated.data, -1,
454 (void *)gd_output.data, gd_output.length, &gd_output.length),
455 "conversion from UTF8 to UTF16LE null terminated");
456 torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated very early");
458 gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10);
460 torture_assert(tctx, convert_string_error_handle(iconv_handle,
462 gd_utf16le_terminated.data, -1,
463 (void *)gd_output.data, gd_output.length, &gd_output.length),
464 "conversion from UTF16LE to UTF8 null terminated");
465 torture_assert_data_blob_equal(tctx, gd_output, gd_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated very early");
470 static bool test_gd_ascii_handle(struct torture_context *tctx)
472 struct smb_iconv_handle *iconv_handle;
473 DATA_BLOB gd_utf8 = base64_decode_data_blob(gd_utf8_base64);
474 DATA_BLOB gd_cp850 = base64_decode_data_blob(gd_cp850_base64);
475 DATA_BLOB gd_iso8859_1 = base64_decode_data_blob(gd_iso8859_1_base64);
476 DATA_BLOB gd_utf16le = base64_decode_data_blob(gd_utf16le_base64);
479 talloc_steal(tctx, gd_utf8.data);
480 talloc_steal(tctx, gd_cp850.data);
481 talloc_steal(tctx, gd_iso8859_1.data);
482 talloc_steal(tctx, gd_utf16le.data);
484 iconv_handle = get_iconv_testing_handle(tctx, "ASCII", "UTF8");
485 torture_assert(tctx, iconv_handle, "getting iconv handle");
487 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
489 gd_utf8.data, gd_utf8.length,
490 (void *)&gd_output.data, &gd_output.length) == false,
491 "conversion from UTF8 to (dos charset) ASCII should fail");
493 gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length);
495 torture_assert(tctx, convert_string_error_handle(iconv_handle,
497 gd_utf8.data, gd_utf8.length,
498 (void *)gd_output.data, gd_output.length,
499 &gd_output.length) == false,
500 "conversion from UTF8 to (dos charset) ASCII should fail");
501 torture_assert_errno_equal(tctx, EILSEQ, "conversion from UTF8 to (dos charset) ISO8859-1 should fail E2BIG");
502 torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
503 torture_assert_data_blob_equal(tctx, gd_output, data_blob_string_const("G"), "partial conversion from UTF8 to (dos charset) ASCII incorrect");
505 /* Short output handling confirmation */
506 gd_output.length = 1;
507 torture_assert(tctx, convert_string_error_handle(iconv_handle,
509 gd_utf8.data, gd_utf8.length,
510 (void *)gd_output.data, gd_output.length,
511 &gd_output.length) == false,
512 "conversion from UTF8 to (dos charset) ASCII should fail due to too short");
513 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to (dos charset) ASCII too short");
514 torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
515 torture_assert_data_blob_equal(tctx, gd_output, data_blob_string_const("G"), "conversion from UTF8 to (dos charset) ASCII incorrect");
517 /* Short output handling confirmation */
518 gd_output.length = 2;
519 torture_assert(tctx, convert_string_error_handle(iconv_handle,
521 gd_utf8.data, gd_utf8.length,
522 (void *)gd_output.data, gd_output.length,
523 &gd_output.length) == false,
524 "conversion from UTF8 to (dos charset) ASCII should fail due to too illigal seqence");
525 torture_assert_errno_equal(tctx, EILSEQ, "conversion from UTF8 to (dos charset) ISO8859-1 should fail EILSEQ");
526 torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 2 char of output");
528 /* Short input handling confirmation */
529 gd_output.length = gd_utf8.length;
530 torture_assert(tctx, convert_string_error_handle(iconv_handle,
533 (void *)gd_output.data, gd_output.length,
534 &gd_output.length) == false,
535 "conversion from UTF8 to (dos charset) ASCII should fail due to too short");
536 torture_assert_errno_equal(tctx, EILSEQ, "conversion from short UTF8 to (dos charset) ASCII should fail EILSEQ");
537 torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
541 static bool test_plato_english_iso8859_cp850_handle(struct torture_context *tctx)
543 struct smb_iconv_handle *iconv_handle;
544 DATA_BLOB plato_english_utf8 = data_blob_string_const(plato_english_ascii);
545 DATA_BLOB plato_english_cp850 = plato_english_utf8;
546 DATA_BLOB plato_english_iso8859_1 = plato_english_utf8;
547 DATA_BLOB plato_english_utf16le = base64_decode_data_blob(plato_english_utf16le_base64);
548 DATA_BLOB plato_english_output;
549 DATA_BLOB plato_english_output2;
551 talloc_steal(tctx, plato_english_utf16le.data);
553 iconv_handle = get_iconv_testing_handle(tctx, "ISO8859-1", "CP850");
554 torture_assert(tctx, iconv_handle, "getting iconv handle");
556 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
558 plato_english_utf8.data, plato_english_utf8.length,
559 (void *)&plato_english_output.data, &plato_english_output.length),
560 "conversion from UTF8 to (dos charset) ISO8859-1");
561 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_iso8859_1, "conversion from UTF8 to (dos charset) ISO8859-1 incorrect");
563 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
565 plato_english_utf8.data, plato_english_utf8.length,
566 (void *)&plato_english_output.data, &plato_english_output.length),
567 "conversion from UTF8 to (unix charset) CP850");
568 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_cp850, "conversion from UTF8 to (unix charset) CP850 incorrect");
570 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
572 plato_english_utf8.data, plato_english_utf8.length,
573 (void *)&plato_english_output.data, &plato_english_output.length),
574 "conversion from UTF8 to UTF8");
575 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF8 to UTF8 incorrect");
577 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
579 plato_english_utf16le.data, plato_english_utf16le.length,
580 (void *)&plato_english_output.data, &plato_english_output.length),
581 "conversion from UTF16LE to (dos charset) ISO8859-1");
582 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_iso8859_1, "conversion from UTF16LE to (dos charset) ISO8859-1 incorrect");
584 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
586 plato_english_output.data, plato_english_output.length,
587 (void *)&plato_english_output2.data, &plato_english_output2.length),
588 "round trip conversion from (dos charset) ISO8859-1 back to UTF16LE");
589 torture_assert_data_blob_equal(tctx, plato_english_output2, plato_english_utf16le, "round trip conversion from (dos charset) ISO8859-1 back to UTF16LE");
591 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
593 plato_english_utf16le.data, plato_english_utf16le.length,
594 (void *)&plato_english_output.data, &plato_english_output.length),
595 "conversion from UTF16LE to UTF8");
596 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF16LE to UTF8 incorrect");
598 torture_assert(tctx, convert_string_error_handle(iconv_handle,
600 plato_english_utf16le.data, plato_english_utf16le.length,
601 (void *)plato_english_output.data, plato_english_output.length,
602 &plato_english_output.length),
603 "conversion from UTF16LE to UTF8");
604 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF16LE to UTF8 incorrect");
606 plato_english_output.length = 5;
607 torture_assert(tctx, convert_string_error_handle(iconv_handle,
609 plato_english_utf16le.data, plato_english_utf16le.length,
610 (void *)plato_english_output.data, plato_english_output.length,
611 &plato_english_output.length) == false,
612 "conversion from UTF16LE to UTF8 should fail due to short output");
613 torture_assert_data_blob_equal(tctx, plato_english_output, data_blob_string_const("What "), "conversion from UTF16LE to UTF8 incorrect");
614 torture_assert_int_equal(tctx, plato_english_output.length, 5, "short conversion failed");
616 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
618 plato_english_utf16le.data, plato_english_utf16le.length,
619 (void *)&plato_english_output.data, &plato_english_output.length),
620 "conversion from UTF16LE to (unix charset) CP850");
621 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_cp850, "conversion from UTF16LE to (unix charset) CP850 incorrect");
623 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
625 plato_english_utf16le.data, plato_english_utf16le.length,
626 (void *)&plato_english_output.data, &plato_english_output.length),
627 "conversion from UTF16LE to UTF8");
628 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF16LE to UTF8 incorrect");
630 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
632 plato_english_iso8859_1.data, plato_english_iso8859_1.length,
633 (void *)&plato_english_output.data, &plato_english_output.length),
634 "conversion from (dos charset) ISO8859-1 to (dos charset) ISO8859-1");
635 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_iso8859_1, "conversion from UTF16LE to (dos charset) ISO8859-1 incorrect");
637 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
639 plato_english_iso8859_1.data, plato_english_iso8859_1.length,
640 (void *)&plato_english_output.data, &plato_english_output.length),
641 "conversion from (dos charset) ISO8859-1 to (unix charset) CP850");
642 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_cp850, "conversion from UTF16LE to (unix charset) CP850 incorrect");
644 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
646 plato_english_iso8859_1.data, plato_english_iso8859_1.length,
647 (void *)&plato_english_output.data, &plato_english_output.length),
648 "conversion from (dos charset) ISO8859-1 to UTF8");
649 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF16LE to UTF8 incorrect");
651 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
653 plato_english_iso8859_1.data, plato_english_iso8859_1.length,
654 (void *)&plato_english_output.data, &plato_english_output.length),
655 "conversion from (dos charset) ISO8859-1 to UTF16LE");
656 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf16le, "conversion from (dos charset) ISO8859-1 to UTF16LE");
660 static bool test_plato_english_minus_1_handle(struct torture_context *tctx)
662 struct smb_iconv_handle *iconv_handle;
663 DATA_BLOB plato_english_utf8 = data_blob_string_const(plato_english_ascii);
664 DATA_BLOB plato_english_utf16le = base64_decode_data_blob(plato_english_utf16le_base64);
665 DATA_BLOB plato_english_output;
666 DATA_BLOB plato_english_utf8_terminated;
667 DATA_BLOB plato_english_utf16le_terminated;
669 talloc_steal(tctx, plato_english_utf16le.data);
671 iconv_handle = get_iconv_testing_handle(tctx, "ISO8859-1", "CP850");
672 torture_assert(tctx, iconv_handle, "getting iconv handle");
674 plato_english_utf8_terminated = data_blob_talloc(tctx, NULL, plato_english_utf8.length + 1);
675 memcpy(plato_english_utf8_terminated.data, plato_english_utf8.data, plato_english_utf8.length);
676 plato_english_utf8_terminated.data[plato_english_utf8.length] = '\0';
678 plato_english_utf16le_terminated = data_blob_talloc(tctx, NULL, plato_english_utf16le.length + 2);
679 memcpy(plato_english_utf16le_terminated.data, plato_english_utf16le.data, plato_english_utf16le.length);
680 plato_english_utf16le_terminated.data[plato_english_utf16le.length] = '\0';
681 plato_english_utf16le_terminated.data[plato_english_utf16le.length + 1] = '\0';
683 plato_english_output = data_blob_talloc(tctx, NULL, plato_english_utf16le.length + 10);
685 torture_assert(tctx, convert_string_error_handle(iconv_handle,
687 plato_english_utf8_terminated.data, -1,
688 (void *)plato_english_output.data, plato_english_output.length, &plato_english_output.length),
689 "conversion from UTF8 to UTF16LE null terminated");
690 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated");
692 torture_assert(tctx, convert_string_error_handle(iconv_handle,
694 plato_english_utf8_terminated.data, -1,
695 (void *)plato_english_output.data, plato_english_utf16le.length, &plato_english_output.length) == false,
696 "conversion from UTF8 to UTF16LE null terminated should fail");
697 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
698 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf16le, "conversion from UTF8 to UTF16LE null terminated");
700 torture_assert(tctx, convert_string_error_handle(iconv_handle,
702 plato_english_utf8_terminated.data, -1,
703 (void *)plato_english_output.data, plato_english_utf16le.length - 1, &plato_english_output.length) == false,
704 "conversion from UTF8 to UTF16LE null terminated should fail");
705 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
707 torture_assert(tctx, convert_string_error_handle(iconv_handle,
709 plato_english_utf8_terminated.data, -1,
710 (void *)plato_english_output.data, plato_english_utf16le.length - 2, &plato_english_output.length) == false,
711 "conversion from UTF8 to UTF16LE null terminated should fail");
712 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
714 plato_english_output = data_blob_talloc(tctx, NULL, plato_english_utf8.length + 10);
716 torture_assert(tctx, convert_string_error_handle(iconv_handle,
718 plato_english_utf16le_terminated.data, -1,
719 (void *)plato_english_output.data, plato_english_output.length, &plato_english_output.length),
720 "conversion from UTF16LE to UTF8 null terminated");
721 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated");
723 torture_assert(tctx, convert_string_error_handle(iconv_handle,
725 plato_english_utf16le_terminated.data, -1,
726 (void *)plato_english_output.data, plato_english_utf8.length, &plato_english_output.length) == false,
727 "conversion from UTF16LE to UTF8 null terminated should fail");
728 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
729 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF16LE to UTF8 null terminated");
731 torture_assert(tctx, convert_string_error_handle(iconv_handle,
733 plato_english_utf16le_terminated.data, -1,
734 (void *)plato_english_output.data, plato_english_utf8.length - 1, &plato_english_output.length) == false,
735 "conversion from UTF16LE to UTF8 null terminated should fail");
736 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
738 torture_assert(tctx, convert_string_error_handle(iconv_handle,
740 plato_english_utf16le_terminated.data, -1,
741 (void *)plato_english_output.data, plato_english_utf8.length - 2, &plato_english_output.length) == false,
742 "conversion from UTF16LE to UTF8 null terminated should fail");
743 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
745 /* Now null terminate the string early, the confirm we don't skip the NULL and convert any further */
746 plato_english_utf8_terminated.data[3] = '\0';
747 plato_english_utf8_terminated.length = 4; /* used for the comparison only */
749 plato_english_utf16le_terminated.data[6] = '\0';
750 plato_english_utf16le_terminated.data[7] = '\0';
751 plato_english_utf16le_terminated.length = 8; /* used for the comparison only */
753 plato_english_output = data_blob_talloc(tctx, NULL, plato_english_utf16le.length + 10);
755 torture_assert(tctx, convert_string_error_handle(iconv_handle,
757 plato_english_utf8_terminated.data, -1,
758 (void *)plato_english_output.data, plato_english_output.length, &plato_english_output.length),
759 "conversion from UTF8 to UTF16LE null terminated");
760 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated early");
762 plato_english_output = data_blob_talloc(tctx, NULL, plato_english_utf8.length + 10);
764 torture_assert(tctx, convert_string_error_handle(iconv_handle,
766 plato_english_utf16le_terminated.data, -1,
767 (void *)plato_english_output.data, plato_english_output.length, &plato_english_output.length),
768 "conversion from UTF16LE to UTF8 null terminated");
769 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated early");
772 /* Now null terminate the string particularly early, the confirm we don't skip the NULL and convert any further */
773 plato_english_utf8_terminated.data[1] = '\0';
774 plato_english_utf8_terminated.length = 2; /* used for the comparison only */
776 plato_english_utf16le_terminated.data[2] = '\0';
777 plato_english_utf16le_terminated.data[3] = '\0';
778 plato_english_utf16le_terminated.length = 4; /* used for the comparison only */
780 plato_english_output = data_blob_talloc(tctx, NULL, plato_english_utf16le.length + 10);
782 torture_assert(tctx, convert_string_error_handle(iconv_handle, CH_UTF8, CH_UTF16LE,
783 plato_english_utf8_terminated.data, -1,
784 (void *)plato_english_output.data, plato_english_output.length, &plato_english_output.length),
785 "conversion from UTF8 to UTF16LE null terminated");
786 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated very early");
788 plato_english_output = data_blob_talloc(tctx, NULL, plato_english_utf8.length + 10);
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_output.length, &plato_english_output.length),
794 "conversion from UTF16LE to UTF8 null terminated");
795 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated very early");
800 static bool test_plato_minus_1_handle(struct torture_context *tctx)
802 struct smb_iconv_handle *iconv_handle;
803 DATA_BLOB plato_utf8 = base64_decode_data_blob(plato_utf8_base64);
804 DATA_BLOB plato_utf16le = base64_decode_data_blob(plato_utf16le_base64);
805 DATA_BLOB plato_output;
806 DATA_BLOB plato_utf8_terminated;
807 DATA_BLOB plato_utf16le_terminated;
809 talloc_steal(tctx, plato_utf8.data);
810 talloc_steal(tctx, plato_utf16le.data);
812 iconv_handle = get_iconv_testing_handle(tctx, "ISO8859-1", "CP850");
813 torture_assert(tctx, iconv_handle, "getting iconv handle");
815 plato_utf8_terminated = data_blob_talloc(tctx, NULL, plato_utf8.length + 1);
816 memcpy(plato_utf8_terminated.data, plato_utf8.data, plato_utf8.length);
817 plato_utf8_terminated.data[plato_utf8.length] = '\0';
819 plato_utf16le_terminated = data_blob_talloc(tctx, NULL, plato_utf16le.length + 2);
820 memcpy(plato_utf16le_terminated.data, plato_utf16le.data, plato_utf16le.length);
821 plato_utf16le_terminated.data[plato_utf16le.length] = '\0';
822 plato_utf16le_terminated.data[plato_utf16le.length + 1] = '\0';
824 plato_output = data_blob_talloc(tctx, NULL, plato_utf16le.length + 10);
826 torture_assert(tctx, convert_string_error_handle(iconv_handle,
828 plato_utf8_terminated.data, -1,
829 (void *)plato_output.data, plato_output.length, &plato_output.length),
830 "conversion from UTF8 to UTF16LE null terminated");
831 torture_assert_data_blob_equal(tctx, plato_output, plato_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated");
833 torture_assert(tctx, convert_string_error_handle(iconv_handle,
835 plato_utf8_terminated.data, -1,
836 (void *)plato_output.data, plato_utf16le.length, &plato_output.length) == false,
837 "conversion from UTF8 to UTF16LE null terminated should fail");
838 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
839 torture_assert_data_blob_equal(tctx, plato_output, plato_utf16le, "conversion from UTF8 to UTF16LE null terminated");
841 torture_assert(tctx, convert_string_error_handle(iconv_handle,
843 plato_utf8_terminated.data, -1,
844 (void *)plato_output.data, plato_utf16le.length - 1, &plato_output.length) == false,
845 "conversion from UTF8 to UTF16LE null terminated should fail");
846 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
848 torture_assert(tctx, convert_string_error_handle(iconv_handle,
850 plato_utf8_terminated.data, -1,
851 (void *)plato_output.data, plato_utf16le.length - 2, &plato_output.length) == false,
852 "conversion from UTF8 to UTF16LE null terminated should fail");
853 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
855 plato_output = data_blob_talloc(tctx, NULL, plato_utf8.length + 10);
857 torture_assert(tctx, convert_string_error_handle(iconv_handle,
859 plato_utf16le_terminated.data, -1,
860 (void *)plato_output.data, plato_output.length, &plato_output.length),
861 "conversion from UTF16LE to UTF8 null terminated");
862 torture_assert_data_blob_equal(tctx, plato_output, plato_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated");
864 torture_assert(tctx, convert_string_error_handle(iconv_handle,
866 plato_utf16le_terminated.data, -1,
867 (void *)plato_output.data, plato_utf8.length, &plato_output.length) == false,
868 "conversion from UTF16LE to UTF8 null terminated should fail");
869 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
870 torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF16LE to UTF8 null terminated");
872 torture_assert(tctx, convert_string_error_handle(iconv_handle,
874 plato_utf16le_terminated.data, -1,
875 (void *)plato_output.data, plato_utf8.length - 1, &plato_output.length) == false,
876 "conversion from UTF16LE to UTF8 null terminated should fail");
877 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
879 torture_assert(tctx, convert_string_error_handle(iconv_handle,
881 plato_utf16le_terminated.data, -1,
882 (void *)plato_output.data, plato_utf8.length - 2, &plato_output.length) == false,
883 "conversion from UTF16LE to UTF8 null terminated should fail");
884 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
886 /* Now null terminate the string early, the confirm we don't skip the NULL and convert any further */
887 plato_utf8_terminated.data[5] = '\0';
888 plato_utf8_terminated.length = 6; /* used for the comparison only */
890 plato_utf16le_terminated.data[4] = '\0';
891 plato_utf16le_terminated.data[5] = '\0';
892 plato_utf16le_terminated.length = 6; /* used for the comparison only */
894 plato_output = data_blob_talloc(tctx, NULL, plato_utf16le.length + 10);
896 torture_assert(tctx, convert_string_error_handle(iconv_handle,
898 plato_utf8_terminated.data, -1,
899 (void *)plato_output.data, plato_output.length, &plato_output.length),
900 "conversion from UTF8 to UTF16LE null terminated");
901 torture_assert_data_blob_equal(tctx, plato_output, plato_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated early");
903 plato_output = data_blob_talloc(tctx, NULL, plato_utf8.length + 10);
905 torture_assert(tctx, convert_string_error_handle(iconv_handle,
907 plato_utf16le_terminated.data, -1,
908 (void *)plato_output.data, plato_output.length, &plato_output.length),
909 "conversion from UTF16LE to UTF8 null terminated");
910 torture_assert_data_blob_equal(tctx, plato_output, plato_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated early");
915 static bool test_plato_cp850_utf8_handle(struct torture_context *tctx)
917 struct smb_iconv_handle *iconv_handle;
918 DATA_BLOB plato_utf8 = base64_decode_data_blob(plato_utf8_base64);
919 DATA_BLOB plato_utf16le = base64_decode_data_blob(plato_utf16le_base64);
920 DATA_BLOB plato_output;
921 DATA_BLOB plato_output2;
923 talloc_steal(tctx, plato_utf8.data);
924 talloc_steal(tctx, plato_utf16le.data);
926 iconv_handle = get_iconv_testing_handle(tctx, "CP850", "UTF8");
927 torture_assert(tctx, iconv_handle, "creating iconv handle");
929 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
931 plato_utf8.data, plato_utf8.length,
932 (void *)&plato_output.data, &plato_output.length),
933 "conversion of UTF8 ancient greek to UTF16 failed");
934 torture_assert_data_blob_equal(tctx, plato_output, plato_utf16le, "conversion from UTF8 to UTF16LE incorrect");
936 torture_assert_int_equal(tctx,
937 strlen_m_ext_handle(iconv_handle,
938 (const char *)plato_utf8.data,
939 CH_UTF8, CH_UTF16LE),
940 plato_output.length / 2,
941 "checking strlen_m_ext of conversion of UTF8 to UTF16LE");
943 memset(plato_output.data, '\0', plato_output.length);
944 torture_assert(tctx, convert_string_error_handle(iconv_handle,
946 plato_utf8.data, plato_utf8.length,
947 (void *)plato_output.data, plato_output.length,
948 &plato_output.length),
949 "conversion of UTF8 ancient greek to UTF16 failed");
950 torture_assert_data_blob_equal(tctx, plato_output, plato_utf16le, "conversion from UTF8 to UTF16LE incorrect");
952 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
954 plato_output.data, plato_output.length,
955 (void *)&plato_output2.data, &plato_output2.length),
956 "conversion of UTF8 ancient greek to UTF16 failed");
957 torture_assert_data_blob_equal(tctx, plato_output2, plato_utf8, "conversion from UTF8 to UTF16LE incorrect");
959 memset(plato_output2.data, '\0', plato_output2.length);
960 torture_assert(tctx, convert_string_error_handle(iconv_handle,
962 plato_output.data, plato_output.length,
963 (void *)plato_output2.data, plato_output2.length, &plato_output2.length),
964 "conversion of UTF8 ancient greek to UTF16 failed");
965 torture_assert_data_blob_equal(tctx, plato_output2, plato_utf8, "conversion from UTF8 to UTF16LE incorrect");
967 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
969 plato_utf8.data, plato_utf8.length,
970 (void *)&plato_output.data, &plato_output.length),
971 "conversion of UTF8 to UTF8");
972 torture_assert_data_blob_equal(tctx, plato_output, plato_utf8,
973 "conversion of UTF8 to UTF8");
974 torture_assert_int_equal(tctx,
975 strlen_m_ext_handle(iconv_handle,
976 (const char *)plato_utf8.data,
979 "checking strlen_m_ext of conversion of UTF8 to UTF8");
980 memset(plato_output.data, '\0', plato_output.length);
981 torture_assert(tctx, convert_string_error_handle(iconv_handle,
983 plato_utf8.data, plato_utf8.length,
984 (void *)plato_output.data, plato_output.length,
985 &plato_output.length),
986 "conversion of UTF8 to UTF8");
988 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
990 plato_utf8.data, plato_utf8.length,
991 (void *)&plato_output.data, &plato_output.length) == false,
992 "conversion of UTF8 ancient greek to DOS charset CP850 should fail");
994 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
996 plato_utf8.data, plato_utf8.length,
997 (void *)&plato_output.data, &plato_output.length),
998 "conversion of UTF16 ancient greek to unix charset UTF8 failed");
999 torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF8 to (unix charset) UTF8 incorrect");
1001 memset(plato_output.data, '\0', plato_output.length);
1002 torture_assert(tctx, convert_string_error_handle(iconv_handle,
1004 plato_utf8.data, plato_utf8.length,
1005 (void *)plato_output.data, plato_output.length,
1006 &plato_output.length),
1007 "conversion of UTF16 ancient greek to unix charset UTF8 failed");
1008 torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF8 to (unix charset) UTF8 incorrect");
1010 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1012 plato_utf8.data, plato_utf8.length,
1013 (void *)&plato_output.data, &plato_output.length),
1014 "conversion of UTF16 ancient greek to unix charset UTF8 failed");
1015 torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF8 to UTF8 incorrect");
1017 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1019 plato_utf16le.data, plato_utf16le.length,
1020 (void *)&plato_output.data, &plato_output.length) == false,
1021 "conversion of UTF16 ancient greek to DOS charset CP850 should fail");
1023 /* Allocate enough space, if it were possible do do the conversion */
1024 plato_output = data_blob_talloc(tctx, NULL, plato_utf16le.length);
1025 torture_assert(tctx, convert_string_error_handle(iconv_handle,
1027 plato_utf16le.data, plato_utf16le.length,
1028 (void *)plato_output.data, plato_output.length,
1029 &plato_output.length) == false,
1030 "conversion of UTF16 ancient greek to DOS charset CP850 should fail");
1031 torture_assert_errno_equal(tctx, EILSEQ, "conversion of UTF16 ancient greek to DOS charset CP850 should fail");
1033 /* Allocate only enough space for a partial conversion */
1034 plato_output = data_blob_talloc(tctx, NULL, 9);
1035 torture_assert(tctx, convert_string_error_handle(iconv_handle,
1036 CH_UTF16LE, CH_UTF8,
1037 plato_utf16le.data, plato_utf16le.length,
1038 (void *)plato_output.data, plato_output.length,
1039 &plato_output.length) == false,
1040 "conversion of UTF16 ancient greek to UTF8 should fail, not enough space");
1041 torture_assert_errno_equal(tctx, E2BIG, "conversion of UTF16 ancient greek to UTF8 should fail, not enough space");
1042 torture_assert_int_equal(tctx, plato_output.length, 8,
1043 "conversion of UTF16 ancient greek to UTF8 should stop on multibyte boundary");
1045 plato_output = data_blob_talloc(tctx, NULL, 2);
1046 torture_assert(tctx, convert_string_error_handle(iconv_handle,
1047 CH_UTF16LE, CH_UTF8,
1048 plato_utf16le.data, plato_utf16le.length,
1049 (void *)plato_output.data, plato_output.length,
1050 &plato_output.length) == false,
1051 "conversion of UTF16 ancient greek to UTF8 should fail, not enough space");
1052 torture_assert_errno_equal(tctx, E2BIG, "conversion of UTF16 ancient greek to UTF8 should fail, not enough space");
1053 torture_assert_int_equal(tctx, plato_output.length, 0,
1054 "conversion of UTF16 ancient greek to UTF8 should stop on multibyte boundary");
1057 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1058 CH_UTF16LE, CH_UNIX,
1059 plato_utf16le.data, plato_utf16le.length,
1060 (void *)&plato_output.data, &plato_output.length),
1061 "conversion of UTF16 ancient greek to unix charset UTF8 failed");
1062 torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF16LE to (unix charset) UTF8 incorrect");
1063 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1064 CH_UTF16LE, CH_UTF8,
1065 plato_utf16le.data, plato_utf16le.length,
1066 (void *)&plato_output.data, &plato_output.length),
1067 "conversion of UTF16 ancient greek to UTF8 failed");
1068 torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF16LE to UTF8 incorrect");
1069 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1070 CH_UTF16LE, CH_UTF8,
1071 plato_utf16le.data, plato_utf16le.length,
1072 (void *)&plato_output.data, &plato_output.length),
1073 "conversion of UTF16 ancient greek to UTF8 failed");
1074 torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF16LE to UTF8 incorrect");
1076 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1077 CH_UTF8, CH_UTF16LE,
1078 plato_output.data, plato_output.length,
1079 (void *)&plato_output2.data, &plato_output2.length),
1080 "round trip conversion of UTF16 ancient greek to UTF8 and back again failed");
1081 torture_assert_data_blob_equal(tctx, plato_output2, plato_utf16le,
1082 "round trip conversion of UTF16 ancient greek to UTF8 and back again failed");
1083 torture_assert_int_equal(tctx,
1084 strlen_m_ext_handle(iconv_handle,
1085 (const char *)plato_output.data,
1086 CH_UTF8, CH_UTF16LE),
1087 plato_output2.length / 2,
1088 "checking strlen_m_ext of round trip conversion of UTF16 latin charset greek to UTF8 and back again");
1090 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1092 plato_output.data, plato_output.length,
1093 (void *)&plato_output2.data, &plato_output2.length),
1094 "conversion of UTF8 to UTF8");
1095 torture_assert_data_blob_equal(tctx, plato_output2, plato_utf8,
1096 "conversion of UTF8 to UTF8");
1097 torture_assert_int_equal(tctx,
1098 strlen_m_ext_handle(iconv_handle,
1099 (const char *)plato_output.data,
1101 plato_output2.length,
1102 "checking strlen_m_ext of conversion of UTF8 to UTF8");
1106 static bool test_plato_latin_cp850_utf8_handle(struct torture_context *tctx)
1108 struct smb_iconv_handle *iconv_handle;
1109 DATA_BLOB plato_latin_utf8 = base64_decode_data_blob(plato_latin_utf8_base64);
1110 DATA_BLOB plato_latin_utf16le = base64_decode_data_blob(plato_latin_utf16le_base64);
1111 DATA_BLOB plato_latin_output;
1112 DATA_BLOB plato_latin_output2;
1114 talloc_steal(tctx, plato_latin_utf8.data);
1115 talloc_steal(tctx, plato_latin_utf16le.data);
1117 iconv_handle = get_iconv_testing_handle(tctx, "CP850", "UTF8");
1118 torture_assert(tctx, iconv_handle, "creating iconv handle");
1120 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1122 plato_latin_utf8.data, plato_latin_utf8.length,
1123 (void *)&plato_latin_output.data, &plato_latin_output.length) == false,
1124 "conversion of UTF8 latin charset greek to DOS charset CP850 should fail");
1126 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1128 plato_latin_utf8.data, plato_latin_utf8.length,
1129 (void *)&plato_latin_output.data, &plato_latin_output.length),
1130 "conversion of UTF16 latin charset greek to unix charset UTF8 failed");
1131 torture_assert_data_blob_equal(tctx, plato_latin_output, plato_latin_utf8, "conversion from UTF8 to (unix charset) UTF8 incorrect");
1133 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1135 plato_latin_utf8.data, plato_latin_utf8.length,
1136 (void *)&plato_latin_output.data, &plato_latin_output.length),
1137 "conversion of UTF16 latin charset greek to unix charset UTF8 failed");
1138 torture_assert_data_blob_equal(tctx, plato_latin_output, plato_latin_utf8, "conversion from UTF8 to UTF8 incorrect");
1140 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1142 plato_latin_utf16le.data, plato_latin_utf16le.length,
1143 (void *)&plato_latin_output.data, &plato_latin_output.length) == false,
1144 "conversion of UTF16 latin charset greek to DOS charset CP850 should fail");
1146 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1147 CH_UTF16LE, CH_UNIX,
1148 plato_latin_utf16le.data, plato_latin_utf16le.length,
1149 (void *)&plato_latin_output.data, &plato_latin_output.length),
1150 "conversion of UTF16 latin charset greek to unix charset UTF8 failed");
1151 torture_assert_data_blob_equal(tctx, plato_latin_output, plato_latin_utf8, "conversion from UTF16LE to (unix charset) CP850 incorrect");
1153 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1154 CH_UTF16LE, CH_UTF8,
1155 plato_latin_utf16le.data, plato_latin_utf16le.length,
1156 (void *)&plato_latin_output.data, &plato_latin_output.length),
1157 "conversion of UTF16 latin charset greek to UTF8 failed");
1158 torture_assert_data_blob_equal(tctx, plato_latin_output, plato_latin_utf8, "conversion from UTF16LE to UTF8 incorrect");
1160 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1161 CH_UTF8, CH_UTF16LE,
1162 plato_latin_output.data, plato_latin_output.length,
1163 (void *)&plato_latin_output2.data, &plato_latin_output2.length),
1164 "round trip conversion of UTF16 latin charset greek to UTF8 and back again failed");
1165 torture_assert_data_blob_equal(tctx, plato_latin_output2, plato_latin_utf16le,
1166 "round trip conversion of UTF16 latin charset greek to UTF8 and back again failed");
1167 torture_assert_int_equal(tctx,
1168 strlen_m_ext_handle(iconv_handle,
1169 (const char *)plato_latin_output.data,
1170 CH_UTF8, CH_UTF16LE),
1171 plato_latin_output2.length / 2,
1172 "checking strlen_m_ext of round trip conversion of UTF16 latin charset greek to UTF8 and back again");
1176 static bool test_gd_case_utf8_handle(struct torture_context *tctx)
1178 struct smb_iconv_handle *iconv_handle;
1179 DATA_BLOB gd_utf8 = base64_decode_data_blob(gd_utf8_base64);
1180 DATA_BLOB gd_utf8_upper = base64_decode_data_blob(gd_utf8_upper_base64);
1181 DATA_BLOB gd_utf8_lower = base64_decode_data_blob(gd_utf8_lower_base64);
1182 char *gd_lower, *gd_upper;
1183 talloc_steal(tctx, gd_utf8.data);
1185 iconv_handle = get_iconv_testing_handle(tctx, "ASCII", "UTF8");
1186 torture_assert(tctx, iconv_handle, "getting utf8 iconv handle");
1188 torture_assert(tctx,
1189 strhasupper_handle(iconv_handle, (const char *)gd_utf8.data),
1190 "GD's name has an upper case character");
1191 torture_assert(tctx,
1192 strhaslower_handle(iconv_handle, (const char *)gd_utf8.data),
1193 "GD's name has an lower case character");
1194 gd_lower = strlower_talloc_handle(iconv_handle, tctx, (const char *)gd_utf8.data);
1195 torture_assert(tctx, gd_lower, "failed to convert GD's name into lower case");
1196 torture_assert_data_blob_equal(tctx, data_blob_string_const(gd_lower), gd_utf8_lower,
1197 "convert GD's name into lower case");
1198 gd_upper = strupper_talloc_n_handle(iconv_handle, tctx, (const char *)gd_utf8.data, gd_utf8.length);
1199 torture_assert(tctx, gd_lower, "failed to convert GD's name into upper case");
1200 torture_assert_data_blob_equal(tctx, data_blob_string_const(gd_upper), gd_utf8_upper,
1201 "convert GD's name into upper case");
1203 torture_assert(tctx,
1204 strhasupper_handle(iconv_handle, gd_upper),
1205 "upper case name has an upper case character");
1206 torture_assert(tctx,
1207 strhaslower_handle(iconv_handle, gd_lower),
1208 "lower case name has an lower case character");
1209 torture_assert(tctx,
1210 strhasupper_handle(iconv_handle, gd_lower) == false,
1211 "lower case name has no upper case character");
1212 torture_assert(tctx,
1213 strhaslower_handle(iconv_handle, gd_upper) == false,
1214 "upper case name has no lower case character");
1216 torture_assert(tctx, strcasecmp_m_handle(iconv_handle, (const char *)gd_utf8.data,
1218 "case insensitive comparison orig/upper");
1219 torture_assert(tctx, strcasecmp_m_handle(iconv_handle, (const char *)gd_utf8.data,
1221 "case insensitive comparison orig/lower");
1222 torture_assert(tctx, strcasecmp_m_handle(iconv_handle, gd_upper,
1224 "case insensitive comparison upper/lower");
1226 /* This string isn't different in length upper/lower */
1227 torture_assert(tctx, strncasecmp_m_handle(iconv_handle, (const char *)gd_utf8.data,
1228 gd_upper, gd_utf8.length) == 0,
1229 "case insensitive comparison orig/upper");
1230 torture_assert(tctx, strncasecmp_m_handle(iconv_handle, (const char *)gd_utf8.data,
1231 gd_lower, gd_utf8.length) == 0,
1232 "case insensitive comparison orig/lower");
1233 torture_assert(tctx, strncasecmp_m_handle(iconv_handle, gd_upper,
1234 gd_lower, gd_utf8.length) == 0,
1235 "case insensitive comparison upper/lower");
1239 static bool test_gd_case_cp850_handle(struct torture_context *tctx)
1241 struct smb_iconv_handle *iconv_handle;
1242 DATA_BLOB gd_cp850 = base64_decode_data_blob(gd_cp850_base64);
1243 DATA_BLOB gd_cp850_upper = base64_decode_data_blob(gd_cp850_upper_base64);
1244 DATA_BLOB gd_cp850_lower = base64_decode_data_blob(gd_cp850_lower_base64);
1245 char *gd_lower, *gd_upper;
1246 talloc_steal(tctx, gd_cp850.data);
1248 iconv_handle = get_iconv_testing_handle(tctx, "ASCII", "CP850");
1249 torture_assert(tctx, iconv_handle, "getting cp850 iconv handle");
1251 torture_assert(tctx,
1252 strhasupper_handle(iconv_handle, (const char *)gd_cp850.data),
1253 "GD's name has an upper case character");
1254 torture_assert(tctx,
1255 strhaslower_handle(iconv_handle, (const char *)gd_cp850.data),
1256 "GD's name has an lower case character");
1257 gd_lower = strlower_talloc_handle(iconv_handle, tctx, (const char *)gd_cp850.data);
1258 torture_assert(tctx, gd_lower, "failed to convert GD's name into lower case");
1259 torture_assert_data_blob_equal(tctx, data_blob_string_const(gd_lower), gd_cp850_lower,
1260 "convert GD's name into lower case");
1261 gd_upper = strupper_talloc_n_handle(iconv_handle, tctx, (const char *)gd_cp850.data, gd_cp850.length);
1262 torture_assert(tctx, gd_lower, "failed to convert GD's name into upper case");
1263 torture_assert_data_blob_equal(tctx, data_blob_string_const(gd_upper), gd_cp850_upper,
1264 "convert GD's name into upper case");
1266 torture_assert(tctx,
1267 strhasupper_handle(iconv_handle, gd_upper),
1268 "upper case name has an upper case character");
1269 torture_assert(tctx,
1270 strhaslower_handle(iconv_handle, gd_lower),
1271 "lower case name has an lower case character");
1272 torture_assert(tctx,
1273 strhasupper_handle(iconv_handle, gd_lower) == false,
1274 "lower case name has no upper case character");
1275 torture_assert(tctx,
1276 strhaslower_handle(iconv_handle, gd_upper) == false,
1277 "upper case name has no lower case character");
1279 torture_assert(tctx, strcasecmp_m_handle(iconv_handle, (const char *)gd_cp850.data,
1281 "case insensitive comparison orig/upper");
1282 torture_assert(tctx, strcasecmp_m_handle(iconv_handle, (const char *)gd_cp850.data,
1284 "case insensitive comparison orig/lower");
1285 torture_assert(tctx, strcasecmp_m_handle(iconv_handle, gd_upper,
1287 "case insensitive comparison upper/lower");
1289 /* This string isn't different in length upper/lower */
1290 torture_assert(tctx, strncasecmp_m_handle(iconv_handle, (const char *)gd_cp850.data,
1291 gd_upper, gd_cp850.length) == 0,
1292 "case insensitive comparison orig/upper");
1293 torture_assert(tctx, strncasecmp_m_handle(iconv_handle, (const char *)gd_cp850.data,
1294 gd_lower, gd_cp850.length) == 0,
1295 "case insensitive comparison orig/lower");
1296 torture_assert(tctx, strncasecmp_m_handle(iconv_handle, gd_upper,
1297 gd_lower, gd_cp850.length) == 0,
1298 "case insensitive comparison upper/lower");
1302 static bool test_plato_case_utf8_handle(struct torture_context *tctx)
1304 struct smb_iconv_handle *iconv_handle;
1305 DATA_BLOB plato_utf8 = base64_decode_data_blob(plato_utf8_base64);
1306 char *plato_lower, *plato_upper;
1307 talloc_steal(tctx, plato_utf8.data);
1309 iconv_handle = get_iconv_testing_handle(tctx, "ASCII", "UTF8");
1310 torture_assert(tctx, iconv_handle, "getting utf8 iconv handle");
1312 torture_assert(tctx,
1313 strhasupper_handle(iconv_handle, (const char *)plato_utf8.data),
1314 "PLATO's apology has an upper case character");
1315 torture_assert(tctx,
1316 strhaslower_handle(iconv_handle, (const char *)plato_utf8.data),
1317 "PLATO's apology has an lower case character");
1318 plato_lower = strlower_talloc_handle(iconv_handle, tctx, (const char *)plato_utf8.data);
1319 torture_assert(tctx, plato_lower, "failed to convert PLATO's apology into lower case");
1320 plato_upper = strupper_talloc_n_handle(iconv_handle, tctx, (const char *)plato_utf8.data, plato_utf8.length);
1321 torture_assert(tctx, plato_lower, "failed to convert PLATO's apology into upper case");
1323 torture_assert(tctx,
1324 strhasupper_handle(iconv_handle, plato_upper),
1325 "upper case string has an upper case character");
1326 torture_assert(tctx,
1327 strhaslower_handle(iconv_handle, plato_lower),
1328 "lower case string has an lower case character");
1329 torture_assert(tctx,
1330 strhasupper_handle(iconv_handle, plato_lower) == false,
1331 "lower case string has no upper case character");
1332 torture_assert(tctx,
1333 strhaslower_handle(iconv_handle, plato_upper) == false,
1334 "upper case string has no lower case character");
1336 torture_assert(tctx, strcasecmp_m_handle(iconv_handle, (const char *)plato_utf8.data,
1338 "case insensitive comparison orig/upper");
1339 torture_assert(tctx, strcasecmp_m_handle(iconv_handle, (const char *)plato_utf8.data,
1341 "case insensitive comparison orig/lower");
1342 torture_assert(tctx, strcasecmp_m_handle(iconv_handle, plato_upper,
1344 "case insensitive comparison upper/lower");
1348 static bool test_gd(struct torture_context *tctx)
1350 DATA_BLOB gd_utf8 = base64_decode_data_blob(gd_utf8_base64);
1351 DATA_BLOB gd_cp850 = base64_decode_data_blob(gd_cp850_base64);
1352 DATA_BLOB gd_iso8859_1 = base64_decode_data_blob(gd_iso8859_1_base64);
1353 DATA_BLOB gd_utf16le = base64_decode_data_blob(gd_utf16le_base64);
1354 DATA_BLOB gd_output;
1357 talloc_steal(tctx, gd_utf8.data);
1358 talloc_steal(tctx, gd_cp850.data);
1359 talloc_steal(tctx, gd_iso8859_1.data);
1360 talloc_steal(tctx, gd_utf16le.data);
1362 torture_assert(tctx, convert_string_talloc(tctx, CH_UTF8, CH_UTF8,
1363 gd_utf8.data, gd_utf8.length,
1364 (void *)&gd_output.data, &gd_output.length),
1365 "conversion from UTF8 to utf8 charset");
1366 saved_len = gd_output.length;
1368 torture_assert(tctx, convert_string_error(CH_UTF8, CH_UTF8,
1369 gd_utf8.data, gd_utf8.length,
1370 (void *)gd_output.data, gd_output.length,
1372 "conversion from UTF8 to utf8 charset");
1374 /* Short output handling confirmation */
1375 gd_output.length = 1;
1376 torture_assert(tctx, convert_string_error(CH_UTF8, CH_UTF8,
1377 gd_utf8.data, gd_utf8.length,
1378 (void *)gd_output.data, gd_output.length,
1379 &gd_output.length) == false,
1380 "conversion from UTF8 to any utf8 charset should fail due to too short");
1381 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to utf8 charset should fail E2BIG");
1382 torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
1383 torture_assert_data_blob_equal(tctx, gd_output, data_blob_string_const("G"), "conversion from UTF8 to utf8 charset incorrect");
1385 #if 0 /* This currently fails as we just copy like-for-like character conversions */
1386 /* Short output handling confirmation */
1387 gd_output.length = 2;
1388 torture_assert(tctx, convert_string_error(CH_UTF8, CH_UTF8,
1389 gd_utf8.data, gd_utf8.length,
1390 (void *)gd_output.data, gd_output.length,
1391 &gd_output.length) == false,
1392 "conversion from UTF8 to utf8 charset should fail due to too short");
1393 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to utf8 charset should fail E2BIG");
1394 torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
1396 /* Short input handling confirmation */
1397 gd_output.length = saved_len;
1398 torture_assert(tctx, convert_string_error(CH_UTF8, CH_UTF8,
1400 (void *)gd_output.data, gd_output.length,
1401 &gd_output.length) == false,
1402 "conversion from UTF8 to UTF8 should fail due to too short");
1403 torture_assert_errno_equal(tctx, EILSEQ, "conversion from short UTF8 to UTF8 should fail EINVAL");
1404 torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
1407 /* Short output handling confirmation */
1408 gd_output.length = 1;
1409 torture_assert(tctx, convert_string_error(CH_UTF16LE, CH_UTF8,
1410 gd_utf16le.data, gd_utf16le.length,
1411 (void *)gd_output.data, gd_output.length,
1412 &gd_output.length) == false,
1413 "conversion from UTF16 to UTF8 should fail due to too short");
1414 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16 to UTF8 should fail E2BIG");
1415 torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
1416 torture_assert_data_blob_equal(tctx, gd_output, data_blob_string_const("G"), "conversion from UTF16 to UTF8 incorrect");
1418 /* Short output handling confirmation */
1419 gd_output.length = 3;
1420 torture_assert(tctx, convert_string_error(CH_UTF16LE, CH_UTF8,
1421 gd_utf16le.data, gd_utf16le.length,
1422 (void *)gd_output.data, gd_output.length,
1423 &gd_output.length) == false,
1424 "conversion from UTF16 to UTF8 should fail due to too short");
1425 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16 to UTF8 should fail E2BIG");
1426 torture_assert_int_equal(tctx, gd_output.length, 3, "Should get 3 bytes output for UTF8");
1428 /* Short input handling confirmation */
1429 gd_output.length = saved_len;
1430 torture_assert(tctx, convert_string_error(CH_UTF16LE, CH_UTF8,
1432 (void *)gd_output.data, gd_output.length,
1433 &gd_output.length) == false,
1434 "conversion from UTF16 to UTF8 should fail due to too short");
1435 torture_assert_errno_equal(tctx, EINVAL, "conversion from short UTF16 to UTF8 should fail EINVAL");
1436 torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
1441 static bool test_plato(struct torture_context *tctx)
1443 DATA_BLOB plato_utf8 = base64_decode_data_blob(plato_utf8_base64);
1444 DATA_BLOB plato_utf16le = base64_decode_data_blob(plato_utf16le_base64);
1445 DATA_BLOB plato_output;
1446 DATA_BLOB plato_output2;
1448 talloc_steal(tctx, plato_utf8.data);
1449 talloc_steal(tctx, plato_utf16le.data);
1451 torture_assert(tctx, convert_string_talloc(tctx,
1452 CH_UTF8, CH_UTF16LE,
1453 plato_utf8.data, plato_utf8.length,
1454 (void *)&plato_output.data, &plato_output.length),
1455 "conversion of UTF8 ancient greek to UTF16 failed");
1456 torture_assert_data_blob_equal(tctx, plato_output, plato_utf16le, "conversion from UTF8 to UTF16LE incorrect");
1458 torture_assert_int_equal(tctx,
1459 strlen_m_ext((const char *)plato_utf8.data,
1460 CH_UTF8, CH_UTF16LE),
1461 plato_output.length / 2,
1462 "checking strlen_m_ext of conversion of UTF8 to UTF16LE");
1464 memset(plato_output.data, '\0', plato_output.length);
1465 torture_assert(tctx, convert_string_error(CH_UTF8, CH_UTF16LE,
1466 plato_utf8.data, plato_utf8.length,
1467 (void *)plato_output.data, plato_output.length,
1468 &plato_output.length),
1469 "conversion of UTF8 ancient greek to UTF16 failed");
1470 torture_assert_data_blob_equal(tctx, plato_output, plato_utf16le, "conversion from UTF8 to UTF16LE incorrect");
1472 torture_assert(tctx, convert_string_talloc(tctx,
1473 CH_UTF16LE, CH_UTF8,
1474 plato_output.data, plato_output.length,
1475 (void *)&plato_output2.data, &plato_output2.length),
1476 "conversion of UTF8 ancient greek to UTF16 failed");
1477 torture_assert_data_blob_equal(tctx, plato_output2, plato_utf8, "conversion from UTF8 to UTF16LE incorrect");
1479 memset(plato_output2.data, '\0', plato_output2.length);
1480 torture_assert(tctx, convert_string_error(CH_UTF16LE, CH_UTF8,
1481 plato_output.data, plato_output.length,
1482 (void *)plato_output2.data, plato_output2.length, &plato_output2.length),
1483 "conversion of UTF8 ancient greek to UTF16 failed");
1484 torture_assert_data_blob_equal(tctx, plato_output2, plato_utf8, "conversion from UTF8 to UTF16LE incorrect");
1486 torture_assert(tctx, convert_string_talloc(tctx,
1488 plato_utf8.data, plato_utf8.length,
1489 (void *)&plato_output.data, &plato_output.length),
1490 "conversion of UTF8 to UTF8");
1491 torture_assert_data_blob_equal(tctx, plato_output, plato_utf8,
1492 "conversion of UTF8 to UTF8");
1493 torture_assert_int_equal(tctx,
1494 strlen_m_ext((const char *)plato_utf8.data,
1496 plato_output.length,
1497 "checking strlen_m_ext of conversion of UTF8 to UTF8");
1498 memset(plato_output.data, '\0', plato_output.length);
1499 torture_assert(tctx, convert_string_error(CH_UTF8, CH_UTF8,
1500 plato_utf8.data, plato_utf8.length,
1501 (void *)plato_output.data, plato_output.length,
1502 &plato_output.length),
1503 "conversion of UTF8 to UTF8");
1504 torture_assert_data_blob_equal(tctx, plato_output, plato_utf8,
1505 "conversion of UTF8 to UTF8");
1507 memset(plato_output.data, '\0', plato_output.length);
1508 torture_assert(tctx, convert_string_error(CH_UTF8, CH_DOS,
1509 plato_utf8.data, plato_utf8.length,
1510 (void *)plato_output.data, plato_output.length,
1511 &plato_output.length) == false,
1512 "conversion of UTF8 to any dos charset should fail");
1513 torture_assert_errno_equal(tctx, EILSEQ, "conversion of UTF16 ancient greek to any DOS charset should fail EILSEQ");
1515 torture_assert(tctx, convert_string_talloc(tctx,
1517 plato_utf8.data, plato_utf8.length,
1518 (void *)&plato_output.data, &plato_output.length) == false,
1519 "conversion of UTF8 ancient greek to any DOS charset should fail");
1521 /* Allocate only enough space for a partial conversion */
1522 plato_output = data_blob_talloc(tctx, NULL, 9);
1523 torture_assert(tctx, convert_string_error(CH_UTF16LE, CH_UTF8,
1524 plato_utf16le.data, plato_utf16le.length,
1525 (void *)plato_output.data, plato_output.length,
1526 &plato_output.length) == false,
1527 "conversion of UTF16 ancient greek to UTF8 should fail, not enough space");
1528 torture_assert_errno_equal(tctx, E2BIG, "conversion of UTF16 ancient greek to UTF8 should fail, not enough space");
1529 torture_assert_int_equal(tctx, plato_output.length, 8,
1530 "conversion of UTF16 ancient greek to UTF8 should stop on multibyte boundary");
1532 plato_output = data_blob_talloc(tctx, NULL, 2);
1533 torture_assert(tctx, convert_string_error(CH_UTF16LE, CH_UTF8,
1534 plato_utf16le.data, plato_utf16le.length,
1535 (void *)plato_output.data, plato_output.length,
1536 &plato_output.length) == false,
1537 "conversion of UTF16 ancient greek to UTF8 should fail, not enough space");
1538 torture_assert_errno_equal(tctx, E2BIG, "conversion of UTF16 ancient greek to UTF8 should fail, not enough space");
1539 torture_assert_int_equal(tctx, plato_output.length, 0,
1540 "conversion of UTF16 ancient greek to UTF8 should stop on multibyte boundary");
1546 static bool test_plato_latin(struct torture_context *tctx)
1548 DATA_BLOB plato_latin_utf8 = base64_decode_data_blob(plato_latin_utf8_base64);
1549 DATA_BLOB plato_latin_utf16le = base64_decode_data_blob(plato_latin_utf16le_base64);
1550 DATA_BLOB plato_latin_output;
1552 talloc_steal(tctx, plato_latin_utf8.data);
1553 talloc_steal(tctx, plato_latin_utf16le.data);
1555 torture_assert(tctx, convert_string_talloc(tctx,
1556 CH_UTF16LE, CH_UTF8,
1557 plato_latin_utf16le.data, plato_latin_utf16le.length,
1558 (void *)&plato_latin_output.data, &plato_latin_output.length),
1559 "conversion of UTF16 latin charset greek to unix charset UTF8 failed");
1560 torture_assert_data_blob_equal(tctx, plato_latin_output, plato_latin_utf8, "conversion from UTF16 to UTF8 incorrect");
1562 torture_assert_int_equal(tctx,
1563 strlen_m_ext((const char *)plato_latin_output.data,
1564 CH_UTF8, CH_UTF16LE),
1565 plato_latin_utf16le.length / 2,
1566 "checking strlen_m_ext UTF16 latin charset greek to UTF8");
1567 torture_assert(tctx, convert_string_talloc(tctx,
1568 CH_UTF8, CH_UTF16LE,
1569 plato_latin_utf8.data, plato_latin_utf8.length,
1570 (void *)&plato_latin_output.data, &plato_latin_output.length),
1571 "conversion of UTF16 latin charset greek to UTF16LE failed");
1572 torture_assert_data_blob_equal(tctx, plato_latin_output, plato_latin_utf16le, "conversion from UTF8 to UTF16LE incorrect");
1577 static bool test_gd_case(struct torture_context *tctx)
1579 DATA_BLOB gd_utf8 = base64_decode_data_blob(gd_utf8_base64);
1582 char *gd_lower, *gd_upper;
1583 talloc_steal(tctx, gd_utf8.data);
1585 torture_assert(tctx, convert_string_talloc(tctx, CH_UTF8, CH_UNIX,
1586 gd_utf8.data, gd_utf8.length,
1587 (void *)&gd_unix, &gd_size),
1588 "conversion of unix charset to UTF8");
1590 gd_lower = strlower_talloc(tctx, gd_unix);
1591 torture_assert(tctx, gd_lower, "failed to convert GD's name into lower case");
1592 gd_upper = strupper_talloc_n(tctx, gd_unix, gd_size);
1593 torture_assert(tctx, gd_lower, "failed to convert GD's name into upper case");
1595 torture_assert(tctx,
1596 strhasupper(gd_unix),
1597 "GD's name has an upper case character");
1598 torture_assert(tctx,
1599 strhaslower(gd_unix),
1600 "GD's name has an lower case character");
1601 torture_assert(tctx,
1602 strhasupper(gd_upper),
1603 "upper case name has an upper case character");
1604 torture_assert(tctx,
1605 strhaslower(gd_lower),
1606 "lower case name has an lower case character");
1607 torture_assert(tctx,
1608 strhasupper(gd_lower) == false,
1609 "lower case name has no upper case character");
1610 torture_assert(tctx,
1611 strhaslower(gd_upper) == false,
1612 "upper case name has no lower case character");
1614 torture_assert(tctx, strcasecmp_m(gd_unix,
1616 "case insensitive comparison orig/upper");
1617 torture_assert(tctx, strcasecmp_m(gd_unix,
1619 "case insensitive comparison orig/lower");
1620 torture_assert(tctx, strcasecmp_m(gd_upper,
1622 "case insensitive comparison upper/lower");
1624 /* This string isn't different in length upper/lower, but just check the first 5 chars */
1625 torture_assert(tctx, strncasecmp_m(gd_unix,
1627 "case insensitive comparison orig/upper");
1628 torture_assert(tctx, strncasecmp_m(gd_unix,
1630 "case insensitive comparison orig/lower");
1631 torture_assert(tctx, strncasecmp_m(gd_upper,
1633 "case insensitive comparison upper/lower");
1637 static bool test_plato_case(struct torture_context *tctx)
1639 DATA_BLOB plato_utf8 = base64_decode_data_blob(plato_utf8_base64);
1641 size_t plato_length;
1642 char *plato_lower, *plato_upper;
1643 talloc_steal(tctx, plato_utf8.data);
1645 torture_assert(tctx, convert_string_talloc(tctx, CH_UTF8, CH_UNIX,
1646 plato_utf8.data, plato_utf8.length,
1647 (void *)&plato_unix, &plato_length),
1648 "conversion of unix charset to UTF8");
1650 torture_assert(tctx,
1651 strhasupper(plato_unix),
1652 "PLATO's apology has an upper case character");
1653 torture_assert(tctx,
1654 strhaslower(plato_unix),
1655 "PLATO's apology has an lower case character");
1656 plato_lower = strlower_talloc(tctx, plato_unix);
1657 torture_assert(tctx, plato_lower, "failed to convert PLATO's apology into lower case");
1658 plato_upper = strupper_talloc_n(tctx, plato_unix, plato_utf8.length);
1659 torture_assert(tctx, plato_lower, "failed to convert PLATO's apology into upper case");
1661 torture_assert(tctx,
1662 strhasupper(plato_upper),
1663 "upper case string has an upper case character");
1664 torture_assert(tctx,
1665 strhaslower(plato_lower),
1666 "lower case string has an lower case character");
1667 torture_assert(tctx,
1668 strhasupper(plato_lower) == false,
1669 "lower case string has no upper case character");
1670 torture_assert(tctx,
1671 strhaslower(plato_upper) == false,
1672 "upper case string has no lower case character");
1674 torture_assert(tctx, strcasecmp_m(plato_unix,
1676 "case insensitive comparison orig/upper");
1677 torture_assert(tctx, strcasecmp_m(plato_unix,
1679 "case insensitive comparison orig/lower");
1680 torture_assert(tctx, strcasecmp_m(plato_upper,
1682 "case insensitive comparison upper/lower");
1686 struct torture_suite *torture_local_convert_string_handle(TALLOC_CTX *mem_ctx)
1688 struct torture_suite *suite = torture_suite_create(mem_ctx, "convert_string_handle");
1690 torture_suite_add_simple_test(suite, "gd_ascii", test_gd_ascii_handle);
1691 torture_suite_add_simple_test(suite, "gd_minus_1", test_gd_minus_1_handle);
1692 torture_suite_add_simple_test(suite, "gd_iso8859_cp850", test_gd_iso8859_cp850_handle);
1693 torture_suite_add_simple_test(suite, "plato_english_iso8859_cp850", test_plato_english_iso8859_cp850_handle);
1694 torture_suite_add_simple_test(suite, "plato_english_minus_1", test_plato_english_minus_1_handle);
1695 torture_suite_add_simple_test(suite, "plato_cp850_utf8", test_plato_cp850_utf8_handle);
1696 torture_suite_add_simple_test(suite, "plato_minus_1", test_plato_minus_1_handle);
1697 torture_suite_add_simple_test(suite, "plato_latin_cp850_utf8", test_plato_latin_cp850_utf8_handle);
1701 struct torture_suite *torture_local_string_case_handle(TALLOC_CTX *mem_ctx)
1703 struct torture_suite *suite = torture_suite_create(mem_ctx, "string_case_handle");
1705 torture_suite_add_simple_test(suite, "gd_case_utf8", test_gd_case_utf8_handle);
1706 torture_suite_add_simple_test(suite, "gd_case_cp850", test_gd_case_cp850_handle);
1707 torture_suite_add_simple_test(suite, "plato_case_utf8", test_plato_case_utf8_handle);
1711 struct torture_suite *torture_local_convert_string(TALLOC_CTX *mem_ctx)
1713 struct torture_suite *suite = torture_suite_create(mem_ctx, "convert_string");
1715 torture_suite_add_simple_test(suite, "gd", test_gd);
1716 torture_suite_add_simple_test(suite, "plato", test_plato);
1717 torture_suite_add_simple_test(suite, "plato_latin", test_plato_latin);
1721 struct torture_suite *torture_local_string_case(TALLOC_CTX *mem_ctx)
1723 struct torture_suite *suite = torture_suite_create(mem_ctx, "string_case_handle");
1725 torture_suite_add_simple_test(suite, "gd_case", test_gd_case);
1726 torture_suite_add_simple_test(suite, "plato_case", test_plato_case);