lib/tls: Change default supported TLS versions.
[Samba.git] / lib / util / charset / tests / convert_string.c
blob92de70295f800da35d694782c8792c88606afe38
1 /*
2 Unix SMB/CIFS implementation.
3 test suite for the charcnv functions
5 Copyright (C) Andrew Bartlett 2011
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "includes.h"
22 #include "torture/torture.h"
23 #include "lib/util/charset/charset.h"
24 #include "param/param.h"
26 struct torture_suite *torture_local_convert_string_handle(TALLOC_CTX *mem_ctx);
27 struct torture_suite *torture_local_string_case_handle(TALLOC_CTX *mem_ctx);
28 struct torture_suite *torture_local_convert_string(TALLOC_CTX *mem_ctx);
29 struct torture_suite *torture_local_string_case(TALLOC_CTX *mem_ctx);
31 /* The text below is in ancient and a latin charset transliteration of
32 * greek, and an english translation. It from Apology by Plato and sourced from
33 * http://en.wikipedia.org/w/index.php?title=Ancient_Greek&oldid=421361065#Example_text
36 const char *plato_english_ascii =
37 "What you, men of Athens, have learned from my accusers, I do not"
38 " know: but I, for my part, nearly forgot who I was thanks to them since"
39 " they spoke so persuasively. And yet, of the truth, they have spoken,"
40 " one might say, nothing at all.";
42 const char *plato_english_utf16le_base64 =
43 "VwBoAGEAdAAgAHkAbwB1ACwAIABtAGUAbgAgAG8AZgAgAEEAdABoAGUAbgBzACwAIABoAGEAdgBl"
44 "ACAAbABlAGEAcgBuAGUAZAAgAGYAcgBvAG0AIABtAHkAIABhAGMAYwB1AHMAZQByAHMALAAgAEkA"
45 "IABkAG8AIABuAG8AdAAgAGsAbgBvAHcAOgAgAGIAdQB0ACAASQAsACAAZgBvAHIAIABtAHkAIABw"
46 "AGEAcgB0ACwAIABuAGUAYQByAGwAeQAgAGYAbwByAGcAbwB0ACAAdwBoAG8AIABJACAAdwBhAHMA"
47 "IAB0AGgAYQBuAGsAcwAgAHQAbwAgAHQAaABlAG0AIABzAGkAbgBjAGUAIAB0AGgAZQB5ACAAcwBw"
48 "AG8AawBlACAAcwBvACAAcABlAHIAcwB1AGEAcwBpAHYAZQBsAHkALgAgAEEAbgBkACAAeQBlAHQA"
49 "LAAgAG8AZgAgAHQAaABlACAAdAByAHUAdABoACwAIAB0AGgAZQB5ACAAaABhAHYAZQAgAHMAcABv"
50 "AGsAZQBuACwAIABvAG4AZQAgAG0AaQBnAGgAdAAgAHMAYQB5ACwAIABuAG8AdABoAGkAbgBnACAA"
51 "YQB0ACAAYQBsAGwALgA=";
53 static const char *plato_utf8_base64 =
54 "4b2Nz4TOuSDOvOG9ss69IOG9kc68zrXhv5bPgiwg4b2mIOG8hM69zrTPgc61z4IgzobOuM63zr3O"
55 "seG/ls6/zrksIM+AzrXPgM+Mzr3OuM6xz4TOtSDhvZHPgOG9uCDPhOG/ts69IOG8kM684b+2zr0g"
56 "zrrOsc+EzrfOs8+Mz4HPic69LCDOv+G9kM66IM6/4by2zrTOsTog4byQzrPhvbwgzrQnIM6/4b2W"
57 "zr0gzrrOseG9tiDOseG9kM+E4b24z4Ig4b2Rz4AnIM6x4b2Qz4Thv7bOvSDhvYDOu86vzrPOv8+F"
58 "IOG8kM68zrHPhc+Ezr/hv6Yg4byQz4DOtc67zrHOuM+MzrzOt869LCDOv+G9lc+Ez4kgz4DOuc64"
59 "zrHOveG/ts+CIOG8lM67zrXOs86/zr0uIM6azrHOr8+Ezr/OuSDhvIDOu863zrjOrc+CIM6zzrUg"
60 "4b2hz4Ig4byUz4DOv8+CIM614bywz4DOteG/ls69IM6/4b2QzrThvbLOvSDOteG8sM+Bzq7Ous6x"
61 "z4POuc69Lg==";
63 static const char *plato_utf16le_base64 =
64 "TR/EA7kDIAC8A3IfvQMgAFEfvAO1A9YfwgMsACAAZh8gAAQfvQO0A8EDtQPCAyAAhgO4A7cDvQOx"
65 "A9YfvwO5AywAIADAA7UDwAPMA70DuAOxA8QDtQMgAFEfwAN4HyAAxAP2H70DIAAQH7wD9h+9AyAA"
66 "ugOxA8QDtwOzA8wDwQPJA70DLAAgAL8DUB+6AyAAvwM2H7QDsQM6ACAAEB+zA3wfIAC0AycAIAC/"
67 "A1YfvQMgALoDsQN2HyAAsQNQH8QDeB/CAyAAUR/AAycAIACxA1AfxAP2H70DIABAH7sDrwOzA78D"
68 "xQMgABAfvAOxA8UDxAO/A+YfIAAQH8ADtQO7A7EDuAPMA7wDtwO9AywAIAC/A1UfxAPJAyAAwAO5"
69 "A7gDsQO9A/YfwgMgABQfuwO1A7MDvwO9Ay4AIACaA7EDrwPEA78DuQMgAAAfuwO3A7gDrQPCAyAA"
70 "swO1AyAAYR/CAyAAFB/AA78DwgMgALUDMB/AA7UD1h+9AyAAvwNQH7QDch+9AyAAtQMwH8EDrgO6"
71 "A7EDwwO5A70DLgA=";
73 static const char *plato_latin_utf8_base64 =
74 "SMOzdGkgbcOobiBodW1lw65zLCDDtCDDoW5kcmVzIEF0aMSTbmHDrm9pLCBwZXDDs250aGF0ZSBo"
75 "dXDDsiB0w7RuIGVtw7RuIGthdMSTZ8OzcsWNbiwgb3VrIG/DrmRhOiBlZ+G5kSBkJyBvw7tuIGth"
76 "w6wgYXV0w7JzIGh1cCcgYXV0xY1uIG9sw61nb3UgZW1hdXRvw7sgZXBlbGF0aMOzbcSTbiwgaG/D"
77 "unTFjSBwaXRoYW7DtHMgw6lsZWdvbi4gS2HDrXRvaSBhbMSTdGjDqXMgZ2UgaMWNcyDDqXBvcyBl"
78 "aXBlw65uIG91ZMOobiBlaXLhuJdrYXNpbi4=";
80 static const char *plato_latin_utf16le_base64 =
81 "SADzAHQAaQAgAG0A6ABuACAAaAB1AG0AZQDuAHMALAAgAPQAIADhAG4AZAByAGUAcwAgAEEAdABo"
82 "ABMBbgBhAO4AbwBpACwAIABwAGUAcADzAG4AdABoAGEAdABlACAAaAB1AHAA8gAgAHQA9ABuACAA"
83 "ZQBtAPQAbgAgAGsAYQB0ABMBZwDzAHIATQFuACwAIABvAHUAawAgAG8A7gBkAGEAOgAgAGUAZwBR"
84 "HiAAZAAnACAAbwD7AG4AIABrAGEA7AAgAGEAdQB0APIAcwAgAGgAdQBwACcAIABhAHUAdABNAW4A"
85 "IABvAGwA7QBnAG8AdQAgAGUAbQBhAHUAdABvAPsAIABlAHAAZQBsAGEAdABoAPMAbQATAW4ALAAg"
86 "AGgAbwD6AHQATQEgAHAAaQB0AGgAYQBuAPQAcwAgAOkAbABlAGcAbwBuAC4AIABLAGEA7QB0AG8A"
87 "aQAgAGEAbAATAXQAaADpAHMAIABnAGUAIABoAE0BcwAgAOkAcABvAHMAIABlAGkAcABlAO4AbgAg"
88 "AG8AdQBkAOgAbgAgAGUAaQByABceawBhAHMAaQBuAC4A";
90 static const char *gd_utf8_base64 = "R8O8bnRoZXIgRGVzY2huZXI=";
91 static const char *gd_utf8_upper_base64 = "R8OcTlRIRVIgREVTQ0hORVI=";
92 static const char *gd_utf8_lower_base64 = "Z8O8bnRoZXIgZGVzY2huZXI=";
93 static const char *gd_cp850_base64 = "R4FudGhlciBEZXNjaG5lcg==";
94 static const char *gd_cp850_upper_base64 = "R5pOVEhFUiBERVNDSE5FUg==";
95 static const char *gd_cp850_lower_base64 = "Z4FudGhlciBkZXNjaG5lcg==";
96 static const char *gd_iso8859_1_base64 = "R/xudGhlciBEZXNjaG5lcg==";
97 static const char *gd_utf16le_base64 = "RwD8AG4AdABoAGUAcgAgAEQAZQBzAGMAaABuAGUAcgA=";
99 static bool test_gd_iso8859_cp850_handle(struct torture_context *tctx)
101 struct smb_iconv_handle *iconv_handle;
102 DATA_BLOB gd_utf8 = base64_decode_data_blob(gd_utf8_base64);
103 DATA_BLOB gd_cp850 = base64_decode_data_blob(gd_cp850_base64);
104 DATA_BLOB gd_iso8859_1 = base64_decode_data_blob(gd_iso8859_1_base64);
105 DATA_BLOB gd_utf16le = base64_decode_data_blob(gd_utf16le_base64);
106 DATA_BLOB gd_output;
107 DATA_BLOB gd_output2;
109 talloc_steal(tctx, gd_utf8.data);
110 talloc_steal(tctx, gd_cp850.data);
111 talloc_steal(tctx, gd_iso8859_1.data);
112 talloc_steal(tctx, gd_utf16le.data);
114 iconv_handle = get_iconv_testing_handle(tctx, "ISO-8859-1", "CP850",
115 lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
116 torture_assert(tctx, iconv_handle, "getting iconv handle");
118 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
119 CH_UTF8, CH_DOS,
120 gd_utf8.data, gd_utf8.length,
121 (void *)&gd_output.data, &gd_output.length),
122 "conversion from UTF8 to (dos charset) ISO-8859-1");
123 torture_assert_data_blob_equal(tctx, gd_output, gd_iso8859_1, "conversion from UTF8 to (dos charset) ISO-8859-1 incorrect");
125 torture_assert(tctx, convert_string_error_handle(iconv_handle,
126 CH_UTF8, CH_DOS,
127 gd_utf8.data, gd_utf8.length,
128 (void *)gd_output.data, gd_output.length,
129 &gd_output.length),
130 "conversion from UTF8 to (dos charset) ISO-8859-1");
131 torture_assert_data_blob_equal(tctx, gd_output, gd_iso8859_1, "conversion from UTF8 to (dos charset) ISO-8859-1 incorrect");
133 /* Short output handling confirmation */
134 gd_output.length = 1;
135 torture_assert(tctx, convert_string_error_handle(iconv_handle,
136 CH_UTF8, CH_DOS,
137 gd_utf8.data, gd_utf8.length,
138 (void *)gd_output.data, gd_output.length,
139 &gd_output.length) == false,
140 "conversion from UTF8 to (dos charset) ISO-8859-1 should fail due to too short");
141 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to (dos charset) ISO-8859-1 should fail E2BIG");
142 torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
143 torture_assert_data_blob_equal(tctx, gd_output, data_blob_string_const("G"), "conversion from UTF8 to (dos charset) ISO-8859-1 incorrect");
145 /* Short output handling confirmation */
146 gd_output.length = 2;
147 torture_assert(tctx, convert_string_error_handle(iconv_handle,
148 CH_UTF8, CH_DOS,
149 gd_utf8.data, gd_utf8.length,
150 (void *)gd_output.data, gd_output.length,
151 &gd_output.length) == false,
152 "conversion from UTF8 to (dos charset) ISO-8859-1 should fail due to too short");
153 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to (dos charset) ISO-8859-1 should fail E2BIG");
154 torture_assert_int_equal(tctx, gd_output.length, 2, "Should only get 2 char of output");
156 /* Short input handling confirmation */
157 gd_output.length = gd_iso8859_1.length;
158 torture_assert(tctx, convert_string_error_handle(iconv_handle,
159 CH_UTF8, CH_DOS,
160 gd_utf8.data, 2,
161 (void *)gd_output.data, gd_output.length,
162 &gd_output.length) == false,
163 "conversion from UTF8 to (dos charset) ISO-8859-1 should fail due to too short");
164 torture_assert_errno_equal(tctx, EILSEQ, "conversion from short UTF8 to (dos charset) ISO-8859-1 should fail EINVAL");
165 torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
167 /* Short output handling confirmation */
168 gd_output.length = 1;
169 torture_assert(tctx, convert_string_error_handle(iconv_handle,
170 CH_UTF16LE, CH_UTF8,
171 gd_utf16le.data, gd_utf16le.length,
172 (void *)gd_output.data, gd_output.length,
173 &gd_output.length) == false,
174 "conversion from UTF16 to UTF8 should fail due to too short");
175 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16 to (utf8 charset) ISO-8859-1 should fail E2BIG");
176 torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
177 torture_assert_data_blob_equal(tctx, gd_output, data_blob_string_const("G"), "conversion from UTF16 to UTF8 incorrect");
179 /* Short output handling confirmation */
180 gd_output.length = 3;
181 torture_assert(tctx, convert_string_error_handle(iconv_handle,
182 CH_UTF16LE, CH_UTF8,
183 gd_utf16le.data, gd_utf16le.length,
184 (void *)gd_output.data, gd_output.length,
185 &gd_output.length) == false,
186 "conversion from UTF16 to UTF8 should fail due to too short");
187 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16 to (utf8 charset) ISO-8859-1 should fail E2BIG");
188 torture_assert_int_equal(tctx, gd_output.length, 3, "Should get 3 bytes output for UTF8");
190 /* Short input handling confirmation */
191 gd_output.length = gd_utf8.length;
192 torture_assert(tctx, convert_string_error_handle(iconv_handle,
193 CH_UTF16LE, CH_UTF8,
194 gd_utf16le.data, 3,
195 (void *)gd_output.data, gd_output.length,
196 &gd_output.length) == false,
197 "conversion from UTF16 to UTF8 should fail due to too short");
198 torture_assert_errno_equal(tctx, EINVAL, "conversion from short UTF16 to UTF8 should fail EINVAL");
199 torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
201 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
202 CH_UTF8, CH_UNIX,
203 gd_utf8.data, gd_utf8.length,
204 (void *)&gd_output.data, &gd_output.length),
205 "conversion from UTF8 to (unix charset) CP850");
206 torture_assert_data_blob_equal(tctx, gd_output, gd_cp850, "conversion from UTF8 to (unix charset) CP850 incorrect");
208 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
209 CH_UTF8, CH_UTF8,
210 gd_utf8.data, gd_utf8.length,
211 (void *)&gd_output.data, &gd_output.length),
212 "conversion from UTF8 to UTF8");
213 torture_assert_data_blob_equal(tctx, gd_output, gd_utf8, "conversion from UTF8 to UTF8 incorrect");
215 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
216 CH_UTF16LE, CH_DOS,
217 gd_utf16le.data, gd_utf16le.length,
218 (void *)&gd_output.data, &gd_output.length),
219 "conversion from UTF16LE to (dos charset) ISO-8859-1");
220 torture_assert_data_blob_equal(tctx, gd_output, gd_iso8859_1, "conversion from UTF16LE to (dos charset) ISO-8859-1 incorrect");
222 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
223 CH_DOS, CH_UTF16LE,
224 gd_output.data, gd_output.length,
225 (void *)&gd_output2.data, &gd_output2.length),
226 "round trip conversion from (dos charset) ISO-8859-1 back to UTF16LE");
227 torture_assert_data_blob_equal(tctx, gd_output2, gd_utf16le, "round trip conversion from (dos charset) ISO-8859-1 back to UTF16LE");
229 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
230 CH_UTF16LE, CH_UNIX,
231 gd_utf16le.data, gd_utf16le.length,
232 (void *)&gd_output.data, &gd_output.length),
233 "conversion from UTF16LE to (unix charset) CP850");
234 torture_assert_data_blob_equal(tctx, gd_output, gd_cp850, "conversion from UTF16LE to (unix charset) CP850 incorrect");
236 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
237 CH_UTF16LE, CH_UTF8,
238 gd_utf16le.data, gd_utf16le.length,
239 (void *)&gd_output.data, &gd_output.length),
240 "conversion from UTF16LE to UTF8");
241 torture_assert_data_blob_equal(tctx, gd_output, gd_utf8, "conversion from UTF16LE to UTF8 incorrect");
243 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
244 CH_DOS, CH_DOS,
245 gd_iso8859_1.data, gd_iso8859_1.length,
246 (void *)&gd_output.data, &gd_output.length),
247 "conversion from (dos charset) ISO-8859-1 to (dos charset) ISO-8859-1");
248 torture_assert_data_blob_equal(tctx, gd_output, gd_iso8859_1, "conversion from UTF16LE to (dos charset) ISO-8859-1 incorrect");
250 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
251 CH_DOS, CH_UNIX,
252 gd_iso8859_1.data, gd_iso8859_1.length,
253 (void *)&gd_output.data, &gd_output.length),
254 "conversion from (dos charset) ISO-8859-1 to (unix charset) CP850");
255 torture_assert_data_blob_equal(tctx, gd_output, gd_cp850, "conversion from UTF16LE to (unix charset) CP850 incorrect");
257 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
258 CH_DOS, CH_UTF8,
259 gd_iso8859_1.data, gd_iso8859_1.length,
260 (void *)&gd_output.data, &gd_output.length),
261 "conversion from (dos charset) ISO-8859-1 to UTF8");
262 torture_assert_data_blob_equal(tctx, gd_output, gd_utf8, "conversion from UTF16LE to UTF8 incorrect");
264 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
265 CH_DOS, CH_UTF16LE,
266 gd_iso8859_1.data, gd_iso8859_1.length,
267 (void *)&gd_output.data, &gd_output.length),
268 "conversion from (dos charset) ISO-8859-1 to UTF16LE");
269 torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le, "conversion from (dos charset) ISO-8859-1 to UTF16LE");
270 torture_assert_int_equal(tctx,
271 strlen_m_ext_handle(iconv_handle,
272 (const char *)gd_iso8859_1.data,
273 CH_DOS, CH_UTF16LE),
274 gd_output.length / 2,
275 "checking strlen_m_ext of round trip conversion of UTF16 latin charset greek to UTF8 and back again");
277 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
278 CH_DOS, CH_UTF8,
279 gd_iso8859_1.data, gd_iso8859_1.length,
280 (void *)&gd_output.data, &gd_output.length),
281 "conversion from (dos charset) ISO-8859-1 to UTF8");
282 torture_assert_data_blob_equal(tctx, gd_output, gd_utf8, "conversion from (dos charset) ISO-8859-1 to UTF8");
283 torture_assert_int_equal(tctx,
284 strlen_m_ext_handle(iconv_handle,
285 (const char *)gd_iso8859_1.data,
286 CH_DOS, CH_UTF8),
287 gd_output.length,
288 "checking strlen_m_ext of conversion from (dos charset) ISO-8859-1 to UTF8");
289 return true;
292 static bool test_gd_minus_1_handle(struct torture_context *tctx)
294 struct smb_iconv_handle *iconv_handle;
295 DATA_BLOB gd_utf8 = base64_decode_data_blob(gd_utf8_base64);
296 DATA_BLOB gd_cp850 = base64_decode_data_blob(gd_cp850_base64);
297 DATA_BLOB gd_utf16le = base64_decode_data_blob(gd_utf16le_base64);
298 DATA_BLOB gd_output;
299 DATA_BLOB gd_utf8_terminated;
300 DATA_BLOB gd_cp850_terminated;
301 DATA_BLOB gd_utf16le_terminated;
303 talloc_steal(tctx, gd_utf8.data);
304 talloc_steal(tctx, gd_cp850.data);
305 talloc_steal(tctx, gd_utf16le.data);
307 iconv_handle = get_iconv_testing_handle(tctx, "CP850", "CP850",
308 lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
309 torture_assert(tctx, iconv_handle, "getting iconv handle");
311 gd_utf8_terminated = data_blob_talloc(tctx, NULL, gd_utf8.length + 1);
312 memcpy(gd_utf8_terminated.data, gd_utf8.data, gd_utf8.length);
313 gd_utf8_terminated.data[gd_utf8.length] = '\0';
315 gd_cp850_terminated = data_blob_talloc(tctx, NULL, gd_cp850.length + 1);
316 memcpy(gd_cp850_terminated.data, gd_cp850.data, gd_cp850.length);
317 gd_cp850_terminated.data[gd_cp850.length] = '\0';
319 gd_utf16le_terminated = data_blob_talloc(tctx, NULL, gd_utf16le.length + 2);
320 memcpy(gd_utf16le_terminated.data, gd_utf16le.data, gd_utf16le.length);
321 gd_utf16le_terminated.data[gd_utf16le.length] = '\0';
322 gd_utf16le_terminated.data[gd_utf16le.length + 1] = '\0';
324 gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
326 torture_assert(tctx, convert_string_error_handle(iconv_handle,
327 CH_UTF8, CH_UTF16LE,
328 gd_utf8_terminated.data, -1,
329 (void *)gd_output.data, gd_output.length, &gd_output.length),
330 "conversion from UTF8 to UTF16LE null terminated");
331 torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated");
333 gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
334 torture_assert(tctx, convert_string_error_handle(iconv_handle,
335 CH_UTF8, CH_UTF16LE,
336 gd_utf8_terminated.data, -1,
337 (void *)gd_output.data, gd_utf16le.length, &gd_output.length) == false,
338 "conversion from UTF8 to UTF16LE null terminated should fail");
339 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
340 torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le, "conversion from UTF8 to UTF16LE null terminated");
342 gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
343 torture_assert(tctx, convert_string_error_handle(iconv_handle,
344 CH_UTF8, CH_UTF16LE,
345 gd_utf8_terminated.data, -1,
346 (void *)gd_output.data, gd_utf16le.length - 1, &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_utf16le.length + 10);
351 torture_assert(tctx, convert_string_error_handle(iconv_handle,
352 CH_UTF8, CH_UTF16LE,
353 gd_utf8_terminated.data, -1,
354 (void *)gd_output.data, gd_utf16le.length - 2, &gd_output.length) == false,
355 "conversion from UTF8 to UTF16LE null terminated should fail");
356 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
358 gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10);
359 torture_assert(tctx, convert_string_error_handle(iconv_handle,
360 CH_UTF16LE, CH_UTF8,
361 gd_utf16le_terminated.data, -1,
362 (void *)gd_output.data, gd_output.length, &gd_output.length),
363 "conversion from UTF16LE to UTF8 null terminated");
364 torture_assert_data_blob_equal(tctx, gd_output, gd_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated");
366 gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10);
368 torture_assert(tctx, convert_string_error_handle(iconv_handle,
369 CH_UTF16LE, CH_UTF8,
370 gd_utf16le_terminated.data, -1,
371 (void *)gd_output.data, gd_utf8.length, &gd_output.length) == false,
372 "conversion from UTF16LE to UTF8 null terminated should fail");
373 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
374 torture_assert_data_blob_equal(tctx, gd_output, gd_utf8, "conversion from UTF16LE to UTF8 null terminated");
376 gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10);
378 torture_assert(tctx, convert_string_error_handle(iconv_handle,
379 CH_UTF16LE, CH_UTF8,
380 gd_utf16le_terminated.data, -1,
381 (void *)gd_output.data, gd_utf8.length - 1, &gd_output.length) == false,
382 "conversion from UTF16LE to UTF8 null terminated should fail");
383 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
385 gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10);
387 torture_assert(tctx, convert_string_error_handle(iconv_handle,
388 CH_UTF16LE, CH_UTF8,
389 gd_utf16le_terminated.data, -1,
390 (void *)gd_output.data, gd_utf8.length - 2, &gd_output.length) == false,
391 "conversion from UTF16LE to UTF8 null terminated should fail");
392 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
394 gd_output = data_blob_talloc(tctx, NULL, gd_cp850.length + 10);
396 torture_assert(tctx, convert_string_error_handle(iconv_handle,
397 CH_UTF16LE, CH_DOS,
398 gd_utf16le_terminated.data, -1,
399 (void *)gd_output.data, gd_output.length, &gd_output.length),
400 "conversion from UTF16LE to CP850 (dos) null terminated");
401 torture_assert_data_blob_equal(tctx, gd_output, gd_cp850_terminated, "conversion from UTF16LE to CP850 (dos) null terminated");
403 /* Now null terminate the string early, the confirm we don't skip the NULL and convert any further */
404 gd_utf8_terminated.data[3] = '\0';
405 gd_utf8_terminated.length = 4; /* used for the comparison only */
407 gd_cp850_terminated.data[2] = '\0';
408 gd_cp850_terminated.length = 3; /* used for the comparison only */
410 gd_utf16le_terminated.data[4] = '\0';
411 gd_utf16le_terminated.data[5] = '\0';
412 gd_utf16le_terminated.length = 6; /* used for the comparison only */
414 gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
416 torture_assert(tctx, convert_string_error_handle(iconv_handle,
417 CH_UTF8, CH_UTF16LE,
418 gd_utf8_terminated.data, -1,
419 (void *)gd_output.data, gd_output.length, &gd_output.length),
420 "conversion from UTF8 to UTF16LE null terminated");
421 torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated early");
423 gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10);
425 torture_assert(tctx, convert_string_error_handle(iconv_handle,
426 CH_UTF16LE, CH_UTF8,
427 gd_utf16le_terminated.data, -1,
428 (void *)gd_output.data, gd_output.length, &gd_output.length),
429 "conversion from UTF16LE to UTF8 null terminated");
430 torture_assert_data_blob_equal(tctx, gd_output, gd_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated early");
432 gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
434 torture_assert(tctx, convert_string_error_handle(iconv_handle,
435 CH_DOS, CH_UTF16LE,
436 gd_cp850_terminated.data, -1,
437 (void *)gd_output.data, gd_output.length, &gd_output.length),
438 "conversion from CP850 to UTF16LE null terminated");
439 torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated early");
441 gd_output = data_blob_talloc(tctx, NULL, gd_cp850.length + 10);
443 torture_assert(tctx, convert_string_error_handle(iconv_handle,
444 CH_UTF16LE, CH_DOS,
445 gd_utf16le_terminated.data, -1,
446 (void *)gd_output.data, gd_output.length, &gd_output.length),
447 "conversion from UTF16LE to UTF8 null terminated");
448 torture_assert_data_blob_equal(tctx, gd_output, gd_cp850_terminated, "conversion from UTF16LE to UTF8 null terminated early");
450 /* Now null terminate the string particularly early, the confirm we don't skip the NULL and convert any further */
451 gd_utf8_terminated.data[1] = '\0';
452 gd_utf8_terminated.length = 2; /* used for the comparison only */
454 gd_utf16le_terminated.data[2] = '\0';
455 gd_utf16le_terminated.data[3] = '\0';
456 gd_utf16le_terminated.length = 4; /* used for the comparison only */
458 gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
460 torture_assert(tctx, convert_string_error_handle(iconv_handle, CH_UTF8, CH_UTF16LE,
461 gd_utf8_terminated.data, -1,
462 (void *)gd_output.data, gd_output.length, &gd_output.length),
463 "conversion from UTF8 to UTF16LE null terminated");
464 torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated very early");
466 gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10);
468 torture_assert(tctx, convert_string_error_handle(iconv_handle,
469 CH_UTF16LE, CH_UTF8,
470 gd_utf16le_terminated.data, -1,
471 (void *)gd_output.data, gd_output.length, &gd_output.length),
472 "conversion from UTF16LE to UTF8 null terminated");
473 torture_assert_data_blob_equal(tctx, gd_output, gd_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated very early");
475 return true;
478 static bool test_gd_ascii_handle(struct torture_context *tctx)
480 struct smb_iconv_handle *iconv_handle;
481 DATA_BLOB gd_utf8 = base64_decode_data_blob(gd_utf8_base64);
482 DATA_BLOB gd_cp850 = base64_decode_data_blob(gd_cp850_base64);
483 DATA_BLOB gd_iso8859_1 = base64_decode_data_blob(gd_iso8859_1_base64);
484 DATA_BLOB gd_utf16le = base64_decode_data_blob(gd_utf16le_base64);
485 DATA_BLOB gd_output;
487 talloc_steal(tctx, gd_utf8.data);
488 talloc_steal(tctx, gd_cp850.data);
489 talloc_steal(tctx, gd_iso8859_1.data);
490 talloc_steal(tctx, gd_utf16le.data);
492 iconv_handle = get_iconv_testing_handle(tctx, "ASCII", "UTF8",
493 lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
494 torture_assert(tctx, iconv_handle, "getting iconv handle");
496 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
497 CH_UTF8, CH_DOS,
498 gd_utf8.data, gd_utf8.length,
499 (void *)&gd_output.data, &gd_output.length) == false,
500 "conversion from UTF8 to (dos charset) ASCII should fail");
502 gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length);
504 torture_assert(tctx, convert_string_error_handle(iconv_handle,
505 CH_UTF8, CH_DOS,
506 gd_utf8.data, gd_utf8.length,
507 (void *)gd_output.data, gd_output.length,
508 &gd_output.length) == false,
509 "conversion from UTF8 to (dos charset) ASCII should fail");
510 torture_assert_errno_equal(tctx, EILSEQ, "conversion from UTF8 to (dos charset) ISO-8859-1 should fail E2BIG");
511 torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
512 torture_assert_data_blob_equal(tctx, gd_output, data_blob_string_const("G"), "partial conversion from UTF8 to (dos charset) ASCII incorrect");
514 /* Short output handling confirmation */
515 gd_output.length = 1;
516 torture_assert(tctx, convert_string_error_handle(iconv_handle,
517 CH_UTF8, CH_DOS,
518 gd_utf8.data, gd_utf8.length,
519 (void *)gd_output.data, gd_output.length,
520 &gd_output.length) == false,
521 "conversion from UTF8 to (dos charset) ASCII should fail due to too short");
522 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to (dos charset) ASCII too short");
523 torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
524 torture_assert_data_blob_equal(tctx, gd_output, data_blob_string_const("G"), "conversion from UTF8 to (dos charset) ASCII incorrect");
526 /* Short output handling confirmation */
527 gd_output.length = 2;
528 torture_assert(tctx, convert_string_error_handle(iconv_handle,
529 CH_UTF8, CH_DOS,
530 gd_utf8.data, gd_utf8.length,
531 (void *)gd_output.data, gd_output.length,
532 &gd_output.length) == false,
533 "conversion from UTF8 to (dos charset) ASCII should fail due to too illigal seqence");
534 torture_assert_errno_equal(tctx, EILSEQ, "conversion from UTF8 to (dos charset) ISO-8859-1 should fail EILSEQ");
535 torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 2 char of output");
537 /* Short input handling confirmation */
538 gd_output.length = gd_utf8.length;
539 torture_assert(tctx, convert_string_error_handle(iconv_handle,
540 CH_UTF8, CH_DOS,
541 gd_utf8.data, 2,
542 (void *)gd_output.data, gd_output.length,
543 &gd_output.length) == false,
544 "conversion from UTF8 to (dos charset) ASCII should fail due to too short");
545 torture_assert_errno_equal(tctx, EILSEQ, "conversion from short UTF8 to (dos charset) ASCII should fail EILSEQ");
546 torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
547 return true;
550 static bool test_plato_english_iso8859_cp850_handle(struct torture_context *tctx)
552 struct smb_iconv_handle *iconv_handle;
553 DATA_BLOB plato_english_utf8 = data_blob_string_const(plato_english_ascii);
554 DATA_BLOB plato_english_cp850 = plato_english_utf8;
555 DATA_BLOB plato_english_iso8859_1 = plato_english_utf8;
556 DATA_BLOB plato_english_utf16le = base64_decode_data_blob(plato_english_utf16le_base64);
557 DATA_BLOB plato_english_output;
558 DATA_BLOB plato_english_output2;
560 talloc_steal(tctx, plato_english_utf16le.data);
562 iconv_handle = get_iconv_testing_handle(tctx, "ISO-8859-1", "CP850",
563 lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
564 torture_assert(tctx, iconv_handle, "getting iconv handle");
566 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
567 CH_UTF8, CH_DOS,
568 plato_english_utf8.data, plato_english_utf8.length,
569 (void *)&plato_english_output.data, &plato_english_output.length),
570 "conversion from UTF8 to (dos charset) ISO-8859-1");
571 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_iso8859_1, "conversion from UTF8 to (dos charset) ISO-8859-1 incorrect");
573 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
574 CH_UTF8, CH_UNIX,
575 plato_english_utf8.data, plato_english_utf8.length,
576 (void *)&plato_english_output.data, &plato_english_output.length),
577 "conversion from UTF8 to (unix charset) CP850");
578 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_cp850, "conversion from UTF8 to (unix charset) CP850 incorrect");
580 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
581 CH_UTF8, CH_UTF8,
582 plato_english_utf8.data, plato_english_utf8.length,
583 (void *)&plato_english_output.data, &plato_english_output.length),
584 "conversion from UTF8 to UTF8");
585 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF8 to UTF8 incorrect");
587 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
588 CH_UTF16LE, CH_DOS,
589 plato_english_utf16le.data, plato_english_utf16le.length,
590 (void *)&plato_english_output.data, &plato_english_output.length),
591 "conversion from UTF16LE to (dos charset) ISO-8859-1");
592 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_iso8859_1, "conversion from UTF16LE to (dos charset) ISO-8859-1 incorrect");
594 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
595 CH_DOS, CH_UTF16LE,
596 plato_english_output.data, plato_english_output.length,
597 (void *)&plato_english_output2.data, &plato_english_output2.length),
598 "round trip conversion from (dos charset) ISO-8859-1 back to UTF16LE");
599 torture_assert_data_blob_equal(tctx, plato_english_output2, plato_english_utf16le, "round trip conversion from (dos charset) ISO-8859-1 back to UTF16LE");
601 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
602 CH_UTF16LE, CH_UTF8,
603 plato_english_utf16le.data, plato_english_utf16le.length,
604 (void *)&plato_english_output.data, &plato_english_output.length),
605 "conversion from UTF16LE to UTF8");
606 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF16LE to UTF8 incorrect");
608 torture_assert(tctx, convert_string_error_handle(iconv_handle,
609 CH_UTF16LE, CH_UTF8,
610 plato_english_utf16le.data, plato_english_utf16le.length,
611 (void *)plato_english_output.data, plato_english_output.length,
612 &plato_english_output.length),
613 "conversion from UTF16LE to UTF8");
614 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF16LE to UTF8 incorrect");
616 plato_english_output.length = 5;
617 torture_assert(tctx, convert_string_error_handle(iconv_handle,
618 CH_UTF16LE, CH_UTF8,
619 plato_english_utf16le.data, plato_english_utf16le.length,
620 (void *)plato_english_output.data, plato_english_output.length,
621 &plato_english_output.length) == false,
622 "conversion from UTF16LE to UTF8 should fail due to short output");
623 torture_assert_data_blob_equal(tctx, plato_english_output, data_blob_string_const("What "), "conversion from UTF16LE to UTF8 incorrect");
624 torture_assert_int_equal(tctx, plato_english_output.length, 5, "short conversion failed");
626 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
627 CH_UTF16LE, CH_UNIX,
628 plato_english_utf16le.data, plato_english_utf16le.length,
629 (void *)&plato_english_output.data, &plato_english_output.length),
630 "conversion from UTF16LE to (unix charset) CP850");
631 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_cp850, "conversion from UTF16LE to (unix charset) CP850 incorrect");
633 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
634 CH_UTF16LE, CH_UTF8,
635 plato_english_utf16le.data, plato_english_utf16le.length,
636 (void *)&plato_english_output.data, &plato_english_output.length),
637 "conversion from UTF16LE to UTF8");
638 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF16LE to UTF8 incorrect");
640 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
641 CH_DOS, CH_DOS,
642 plato_english_iso8859_1.data, plato_english_iso8859_1.length,
643 (void *)&plato_english_output.data, &plato_english_output.length),
644 "conversion from (dos charset) ISO-8859-1 to (dos charset) ISO-8859-1");
645 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_iso8859_1, "conversion from UTF16LE to (dos charset) ISO-8859-1 incorrect");
647 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
648 CH_DOS, CH_UNIX,
649 plato_english_iso8859_1.data, plato_english_iso8859_1.length,
650 (void *)&plato_english_output.data, &plato_english_output.length),
651 "conversion from (dos charset) ISO-8859-1 to (unix charset) CP850");
652 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_cp850, "conversion from UTF16LE to (unix charset) CP850 incorrect");
654 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
655 CH_DOS, CH_UTF8,
656 plato_english_iso8859_1.data, plato_english_iso8859_1.length,
657 (void *)&plato_english_output.data, &plato_english_output.length),
658 "conversion from (dos charset) ISO-8859-1 to UTF8");
659 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF16LE to UTF8 incorrect");
661 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
662 CH_DOS, CH_UTF16LE,
663 plato_english_iso8859_1.data, plato_english_iso8859_1.length,
664 (void *)&plato_english_output.data, &plato_english_output.length),
665 "conversion from (dos charset) ISO-8859-1 to UTF16LE");
666 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf16le, "conversion from (dos charset) ISO-8859-1 to UTF16LE");
667 return true;
670 static bool test_plato_english_minus_1_handle(struct torture_context *tctx)
672 struct smb_iconv_handle *iconv_handle;
673 DATA_BLOB plato_english_utf8 = data_blob_string_const(plato_english_ascii);
674 DATA_BLOB plato_english_utf16le = base64_decode_data_blob(plato_english_utf16le_base64);
675 DATA_BLOB plato_english_output;
676 DATA_BLOB plato_english_utf8_terminated;
677 DATA_BLOB plato_english_utf16le_terminated;
679 talloc_steal(tctx, plato_english_utf16le.data);
681 iconv_handle = get_iconv_testing_handle(tctx, "ISO-8859-1", "CP850",
682 lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
683 torture_assert(tctx, iconv_handle, "getting iconv handle");
685 plato_english_utf8_terminated = data_blob_talloc(tctx, NULL, plato_english_utf8.length + 1);
686 memcpy(plato_english_utf8_terminated.data, plato_english_utf8.data, plato_english_utf8.length);
687 plato_english_utf8_terminated.data[plato_english_utf8.length] = '\0';
689 plato_english_utf16le_terminated = data_blob_talloc(tctx, NULL, plato_english_utf16le.length + 2);
690 memcpy(plato_english_utf16le_terminated.data, plato_english_utf16le.data, plato_english_utf16le.length);
691 plato_english_utf16le_terminated.data[plato_english_utf16le.length] = '\0';
692 plato_english_utf16le_terminated.data[plato_english_utf16le.length + 1] = '\0';
694 plato_english_output = data_blob_talloc(tctx, NULL, plato_english_utf16le.length + 10);
696 torture_assert(tctx, convert_string_error_handle(iconv_handle,
697 CH_UTF8, CH_UTF16LE,
698 plato_english_utf8_terminated.data, -1,
699 (void *)plato_english_output.data, plato_english_output.length, &plato_english_output.length),
700 "conversion from UTF8 to UTF16LE null terminated");
701 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated");
703 torture_assert(tctx, convert_string_error_handle(iconv_handle,
704 CH_UTF8, CH_UTF16LE,
705 plato_english_utf8_terminated.data, -1,
706 (void *)plato_english_output.data, plato_english_utf16le.length, &plato_english_output.length) == false,
707 "conversion from UTF8 to UTF16LE null terminated should fail");
708 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
709 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf16le, "conversion from UTF8 to UTF16LE null terminated");
711 torture_assert(tctx, convert_string_error_handle(iconv_handle,
712 CH_UTF8, CH_UTF16LE,
713 plato_english_utf8_terminated.data, -1,
714 (void *)plato_english_output.data, plato_english_utf16le.length - 1, &plato_english_output.length) == false,
715 "conversion from UTF8 to UTF16LE null terminated should fail");
716 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
718 torture_assert(tctx, convert_string_error_handle(iconv_handle,
719 CH_UTF8, CH_UTF16LE,
720 plato_english_utf8_terminated.data, -1,
721 (void *)plato_english_output.data, plato_english_utf16le.length - 2, &plato_english_output.length) == false,
722 "conversion from UTF8 to UTF16LE null terminated should fail");
723 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
725 plato_english_output = data_blob_talloc(tctx, NULL, plato_english_utf8.length + 10);
727 torture_assert(tctx, convert_string_error_handle(iconv_handle,
728 CH_UTF16LE, CH_UTF8,
729 plato_english_utf16le_terminated.data, -1,
730 (void *)plato_english_output.data, plato_english_output.length, &plato_english_output.length),
731 "conversion from UTF16LE to UTF8 null terminated");
732 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated");
734 torture_assert(tctx, convert_string_error_handle(iconv_handle,
735 CH_UTF16LE, CH_UTF8,
736 plato_english_utf16le_terminated.data, -1,
737 (void *)plato_english_output.data, plato_english_utf8.length, &plato_english_output.length) == false,
738 "conversion from UTF16LE to UTF8 null terminated should fail");
739 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
740 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF16LE to UTF8 null terminated");
742 torture_assert(tctx, convert_string_error_handle(iconv_handle,
743 CH_UTF16LE, CH_UTF8,
744 plato_english_utf16le_terminated.data, -1,
745 (void *)plato_english_output.data, plato_english_utf8.length - 1, &plato_english_output.length) == false,
746 "conversion from UTF16LE to UTF8 null terminated should fail");
747 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
749 torture_assert(tctx, convert_string_error_handle(iconv_handle,
750 CH_UTF16LE, CH_UTF8,
751 plato_english_utf16le_terminated.data, -1,
752 (void *)plato_english_output.data, plato_english_utf8.length - 2, &plato_english_output.length) == false,
753 "conversion from UTF16LE to UTF8 null terminated should fail");
754 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
756 /* Now null terminate the string early, the confirm we don't skip the NULL and convert any further */
757 plato_english_utf8_terminated.data[3] = '\0';
758 plato_english_utf8_terminated.length = 4; /* used for the comparison only */
760 plato_english_utf16le_terminated.data[6] = '\0';
761 plato_english_utf16le_terminated.data[7] = '\0';
762 plato_english_utf16le_terminated.length = 8; /* used for the comparison only */
764 plato_english_output = data_blob_talloc(tctx, NULL, plato_english_utf16le.length + 10);
766 torture_assert(tctx, convert_string_error_handle(iconv_handle,
767 CH_UTF8, CH_UTF16LE,
768 plato_english_utf8_terminated.data, -1,
769 (void *)plato_english_output.data, plato_english_output.length, &plato_english_output.length),
770 "conversion from UTF8 to UTF16LE null terminated");
771 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated early");
773 plato_english_output = data_blob_talloc(tctx, NULL, plato_english_utf8.length + 10);
775 torture_assert(tctx, convert_string_error_handle(iconv_handle,
776 CH_UTF16LE, CH_UTF8,
777 plato_english_utf16le_terminated.data, -1,
778 (void *)plato_english_output.data, plato_english_output.length, &plato_english_output.length),
779 "conversion from UTF16LE to UTF8 null terminated");
780 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated early");
783 /* Now null terminate the string particularly early, the confirm we don't skip the NULL and convert any further */
784 plato_english_utf8_terminated.data[1] = '\0';
785 plato_english_utf8_terminated.length = 2; /* used for the comparison only */
787 plato_english_utf16le_terminated.data[2] = '\0';
788 plato_english_utf16le_terminated.data[3] = '\0';
789 plato_english_utf16le_terminated.length = 4; /* used for the comparison only */
791 plato_english_output = data_blob_talloc(tctx, NULL, plato_english_utf16le.length + 10);
793 torture_assert(tctx, convert_string_error_handle(iconv_handle, CH_UTF8, CH_UTF16LE,
794 plato_english_utf8_terminated.data, -1,
795 (void *)plato_english_output.data, plato_english_output.length, &plato_english_output.length),
796 "conversion from UTF8 to UTF16LE null terminated");
797 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated very early");
799 plato_english_output = data_blob_talloc(tctx, NULL, plato_english_utf8.length + 10);
801 torture_assert(tctx, convert_string_error_handle(iconv_handle,
802 CH_UTF16LE, CH_UTF8,
803 plato_english_utf16le_terminated.data, -1,
804 (void *)plato_english_output.data, plato_english_output.length, &plato_english_output.length),
805 "conversion from UTF16LE to UTF8 null terminated");
806 torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated very early");
808 return true;
811 static bool test_plato_minus_1_handle(struct torture_context *tctx)
813 struct smb_iconv_handle *iconv_handle;
814 DATA_BLOB plato_utf8 = base64_decode_data_blob(plato_utf8_base64);
815 DATA_BLOB plato_utf16le = base64_decode_data_blob(plato_utf16le_base64);
816 DATA_BLOB plato_output;
817 DATA_BLOB plato_utf8_terminated;
818 DATA_BLOB plato_utf16le_terminated;
820 talloc_steal(tctx, plato_utf8.data);
821 talloc_steal(tctx, plato_utf16le.data);
823 iconv_handle = get_iconv_testing_handle(tctx, "ISO-8859-1", "CP850",
824 lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
825 torture_assert(tctx, iconv_handle, "getting iconv handle");
827 plato_utf8_terminated = data_blob_talloc(tctx, NULL, plato_utf8.length + 1);
828 memcpy(plato_utf8_terminated.data, plato_utf8.data, plato_utf8.length);
829 plato_utf8_terminated.data[plato_utf8.length] = '\0';
831 plato_utf16le_terminated = data_blob_talloc(tctx, NULL, plato_utf16le.length + 2);
832 memcpy(plato_utf16le_terminated.data, plato_utf16le.data, plato_utf16le.length);
833 plato_utf16le_terminated.data[plato_utf16le.length] = '\0';
834 plato_utf16le_terminated.data[plato_utf16le.length + 1] = '\0';
836 plato_output = data_blob_talloc(tctx, NULL, plato_utf16le.length + 10);
838 torture_assert(tctx, convert_string_error_handle(iconv_handle,
839 CH_UTF8, CH_UTF16LE,
840 plato_utf8_terminated.data, -1,
841 (void *)plato_output.data, plato_output.length, &plato_output.length),
842 "conversion from UTF8 to UTF16LE null terminated");
843 torture_assert_data_blob_equal(tctx, plato_output, plato_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated");
845 torture_assert(tctx, convert_string_error_handle(iconv_handle,
846 CH_UTF8, CH_UTF16LE,
847 plato_utf8_terminated.data, -1,
848 (void *)plato_output.data, plato_utf16le.length, &plato_output.length) == false,
849 "conversion from UTF8 to UTF16LE null terminated should fail");
850 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
851 torture_assert_data_blob_equal(tctx, plato_output, plato_utf16le, "conversion from UTF8 to UTF16LE null terminated");
853 torture_assert(tctx, convert_string_error_handle(iconv_handle,
854 CH_UTF8, CH_UTF16LE,
855 plato_utf8_terminated.data, -1,
856 (void *)plato_output.data, plato_utf16le.length - 1, &plato_output.length) == false,
857 "conversion from UTF8 to UTF16LE null terminated should fail");
858 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
860 torture_assert(tctx, convert_string_error_handle(iconv_handle,
861 CH_UTF8, CH_UTF16LE,
862 plato_utf8_terminated.data, -1,
863 (void *)plato_output.data, plato_utf16le.length - 2, &plato_output.length) == false,
864 "conversion from UTF8 to UTF16LE null terminated should fail");
865 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
867 plato_output = data_blob_talloc(tctx, NULL, plato_utf8.length + 10);
869 torture_assert(tctx, convert_string_error_handle(iconv_handle,
870 CH_UTF16LE, CH_UTF8,
871 plato_utf16le_terminated.data, -1,
872 (void *)plato_output.data, plato_output.length, &plato_output.length),
873 "conversion from UTF16LE to UTF8 null terminated");
874 torture_assert_data_blob_equal(tctx, plato_output, plato_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated");
876 torture_assert(tctx, convert_string_error_handle(iconv_handle,
877 CH_UTF16LE, CH_UTF8,
878 plato_utf16le_terminated.data, -1,
879 (void *)plato_output.data, plato_utf8.length, &plato_output.length) == false,
880 "conversion from UTF16LE to UTF8 null terminated should fail");
881 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
882 torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF16LE to UTF8 null terminated");
884 torture_assert(tctx, convert_string_error_handle(iconv_handle,
885 CH_UTF16LE, CH_UTF8,
886 plato_utf16le_terminated.data, -1,
887 (void *)plato_output.data, plato_utf8.length - 1, &plato_output.length) == false,
888 "conversion from UTF16LE to UTF8 null terminated should fail");
889 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
891 torture_assert(tctx, convert_string_error_handle(iconv_handle,
892 CH_UTF16LE, CH_UTF8,
893 plato_utf16le_terminated.data, -1,
894 (void *)plato_output.data, plato_utf8.length - 2, &plato_output.length) == false,
895 "conversion from UTF16LE to UTF8 null terminated should fail");
896 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
898 /* Now null terminate the string early, the confirm we don't skip the NULL and convert any further */
899 plato_utf8_terminated.data[5] = '\0';
900 plato_utf8_terminated.length = 6; /* used for the comparison only */
902 plato_utf16le_terminated.data[4] = '\0';
903 plato_utf16le_terminated.data[5] = '\0';
904 plato_utf16le_terminated.length = 6; /* used for the comparison only */
906 plato_output = data_blob_talloc(tctx, NULL, plato_utf16le.length + 10);
908 torture_assert(tctx, convert_string_error_handle(iconv_handle,
909 CH_UTF8, CH_UTF16LE,
910 plato_utf8_terminated.data, -1,
911 (void *)plato_output.data, plato_output.length, &plato_output.length),
912 "conversion from UTF8 to UTF16LE null terminated");
913 torture_assert_data_blob_equal(tctx, plato_output, plato_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated early");
915 plato_output = data_blob_talloc(tctx, NULL, plato_utf8.length + 10);
917 torture_assert(tctx, convert_string_error_handle(iconv_handle,
918 CH_UTF16LE, CH_UTF8,
919 plato_utf16le_terminated.data, -1,
920 (void *)plato_output.data, plato_output.length, &plato_output.length),
921 "conversion from UTF16LE to UTF8 null terminated");
922 torture_assert_data_blob_equal(tctx, plato_output, plato_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated early");
924 return true;
927 static bool test_plato_cp850_utf8_handle(struct torture_context *tctx)
929 struct smb_iconv_handle *iconv_handle;
930 DATA_BLOB plato_utf8 = base64_decode_data_blob(plato_utf8_base64);
931 DATA_BLOB plato_utf16le = base64_decode_data_blob(plato_utf16le_base64);
932 DATA_BLOB plato_output;
933 DATA_BLOB plato_output2;
935 talloc_steal(tctx, plato_utf8.data);
936 talloc_steal(tctx, plato_utf16le.data);
938 iconv_handle = get_iconv_testing_handle(tctx, "CP850", "UTF8",
939 lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
940 torture_assert(tctx, iconv_handle, "creating iconv handle");
942 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
943 CH_UTF8, CH_UTF16LE,
944 plato_utf8.data, plato_utf8.length,
945 (void *)&plato_output.data, &plato_output.length),
946 "conversion of UTF8 ancient greek to UTF16 failed");
947 torture_assert_data_blob_equal(tctx, plato_output, plato_utf16le, "conversion from UTF8 to UTF16LE incorrect");
949 torture_assert_int_equal(tctx,
950 strlen_m_ext_handle(iconv_handle,
951 (const char *)plato_utf8.data,
952 CH_UTF8, CH_UTF16LE),
953 plato_output.length / 2,
954 "checking strlen_m_ext of conversion of UTF8 to UTF16LE");
956 memset(plato_output.data, '\0', plato_output.length);
957 torture_assert(tctx, convert_string_error_handle(iconv_handle,
958 CH_UTF8, CH_UTF16LE,
959 plato_utf8.data, plato_utf8.length,
960 (void *)plato_output.data, plato_output.length,
961 &plato_output.length),
962 "conversion of UTF8 ancient greek to UTF16 failed");
963 torture_assert_data_blob_equal(tctx, plato_output, plato_utf16le, "conversion from UTF8 to UTF16LE incorrect");
965 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
966 CH_UTF16LE, CH_UTF8,
967 plato_output.data, plato_output.length,
968 (void *)&plato_output2.data, &plato_output2.length),
969 "conversion of UTF8 ancient greek to UTF16 failed");
970 torture_assert_data_blob_equal(tctx, plato_output2, plato_utf8, "conversion from UTF8 to UTF16LE incorrect");
972 memset(plato_output2.data, '\0', plato_output2.length);
973 torture_assert(tctx, convert_string_error_handle(iconv_handle,
974 CH_UTF16LE, CH_UTF8,
975 plato_output.data, plato_output.length,
976 (void *)plato_output2.data, plato_output2.length, &plato_output2.length),
977 "conversion of UTF8 ancient greek to UTF16 failed");
978 torture_assert_data_blob_equal(tctx, plato_output2, plato_utf8, "conversion from UTF8 to UTF16LE incorrect");
980 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
981 CH_UTF8, CH_UTF8,
982 plato_utf8.data, plato_utf8.length,
983 (void *)&plato_output.data, &plato_output.length),
984 "conversion of UTF8 to UTF8");
985 torture_assert_data_blob_equal(tctx, plato_output, plato_utf8,
986 "conversion of UTF8 to UTF8");
987 torture_assert_int_equal(tctx,
988 strlen_m_ext_handle(iconv_handle,
989 (const char *)plato_utf8.data,
990 CH_UTF8, CH_UTF8),
991 plato_output.length,
992 "checking strlen_m_ext of conversion of UTF8 to UTF8");
993 memset(plato_output.data, '\0', plato_output.length);
994 torture_assert(tctx, convert_string_error_handle(iconv_handle,
995 CH_UTF8, CH_UTF8,
996 plato_utf8.data, plato_utf8.length,
997 (void *)plato_output.data, plato_output.length,
998 &plato_output.length),
999 "conversion of UTF8 to UTF8");
1001 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1002 CH_UTF8, CH_DOS,
1003 plato_utf8.data, plato_utf8.length,
1004 (void *)&plato_output.data, &plato_output.length) == false,
1005 "conversion of UTF8 ancient greek to DOS charset CP850 should fail");
1007 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1008 CH_UTF8, CH_UNIX,
1009 plato_utf8.data, plato_utf8.length,
1010 (void *)&plato_output.data, &plato_output.length),
1011 "conversion of UTF16 ancient greek to unix charset UTF8 failed");
1012 torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF8 to (unix charset) UTF8 incorrect");
1014 memset(plato_output.data, '\0', plato_output.length);
1015 torture_assert(tctx, convert_string_error_handle(iconv_handle,
1016 CH_UTF8, CH_UNIX,
1017 plato_utf8.data, plato_utf8.length,
1018 (void *)plato_output.data, plato_output.length,
1019 &plato_output.length),
1020 "conversion of UTF16 ancient greek to unix charset UTF8 failed");
1021 torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF8 to (unix charset) UTF8 incorrect");
1023 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1024 CH_UTF8, CH_UTF8,
1025 plato_utf8.data, plato_utf8.length,
1026 (void *)&plato_output.data, &plato_output.length),
1027 "conversion of UTF16 ancient greek to unix charset UTF8 failed");
1028 torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF8 to UTF8 incorrect");
1030 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1031 CH_UTF16LE, CH_DOS,
1032 plato_utf16le.data, plato_utf16le.length,
1033 (void *)&plato_output.data, &plato_output.length) == false,
1034 "conversion of UTF16 ancient greek to DOS charset CP850 should fail");
1036 /* Allocate enough space, if it were possible do do the conversion */
1037 plato_output = data_blob_talloc(tctx, NULL, plato_utf16le.length);
1038 torture_assert(tctx, convert_string_error_handle(iconv_handle,
1039 CH_UTF16LE, CH_DOS,
1040 plato_utf16le.data, plato_utf16le.length,
1041 (void *)plato_output.data, plato_output.length,
1042 &plato_output.length) == false,
1043 "conversion of UTF16 ancient greek to DOS charset CP850 should fail");
1044 torture_assert_errno_equal(tctx, EILSEQ, "conversion of UTF16 ancient greek to DOS charset CP850 should fail");
1046 /* Allocate only enough space for a partial conversion */
1047 plato_output = data_blob_talloc(tctx, NULL, 9);
1048 torture_assert(tctx, convert_string_error_handle(iconv_handle,
1049 CH_UTF16LE, CH_UTF8,
1050 plato_utf16le.data, plato_utf16le.length,
1051 (void *)plato_output.data, plato_output.length,
1052 &plato_output.length) == false,
1053 "conversion of UTF16 ancient greek to UTF8 should fail, not enough space");
1054 torture_assert_errno_equal(tctx, E2BIG, "conversion of UTF16 ancient greek to UTF8 should fail, not enough space");
1055 torture_assert_int_equal(tctx, plato_output.length, 8,
1056 "conversion of UTF16 ancient greek to UTF8 should stop on multibyte boundary");
1058 plato_output = data_blob_talloc(tctx, NULL, 2);
1059 torture_assert(tctx, convert_string_error_handle(iconv_handle,
1060 CH_UTF16LE, CH_UTF8,
1061 plato_utf16le.data, plato_utf16le.length,
1062 (void *)plato_output.data, plato_output.length,
1063 &plato_output.length) == false,
1064 "conversion of UTF16 ancient greek to UTF8 should fail, not enough space");
1065 torture_assert_errno_equal(tctx, E2BIG, "conversion of UTF16 ancient greek to UTF8 should fail, not enough space");
1066 torture_assert_int_equal(tctx, plato_output.length, 0,
1067 "conversion of UTF16 ancient greek to UTF8 should stop on multibyte boundary");
1070 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1071 CH_UTF16LE, CH_UNIX,
1072 plato_utf16le.data, plato_utf16le.length,
1073 (void *)&plato_output.data, &plato_output.length),
1074 "conversion of UTF16 ancient greek to unix charset UTF8 failed");
1075 torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF16LE to (unix charset) UTF8 incorrect");
1076 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1077 CH_UTF16LE, CH_UTF8,
1078 plato_utf16le.data, plato_utf16le.length,
1079 (void *)&plato_output.data, &plato_output.length),
1080 "conversion of UTF16 ancient greek to UTF8 failed");
1081 torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF16LE to UTF8 incorrect");
1082 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1083 CH_UTF16LE, CH_UTF8,
1084 plato_utf16le.data, plato_utf16le.length,
1085 (void *)&plato_output.data, &plato_output.length),
1086 "conversion of UTF16 ancient greek to UTF8 failed");
1087 torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF16LE to UTF8 incorrect");
1089 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1090 CH_UTF8, CH_UTF16LE,
1091 plato_output.data, plato_output.length,
1092 (void *)&plato_output2.data, &plato_output2.length),
1093 "round trip conversion of UTF16 ancient greek to UTF8 and back again failed");
1094 torture_assert_data_blob_equal(tctx, plato_output2, plato_utf16le,
1095 "round trip conversion of UTF16 ancient greek to UTF8 and back again failed");
1096 torture_assert_int_equal(tctx,
1097 strlen_m_ext_handle(iconv_handle,
1098 (const char *)plato_output.data,
1099 CH_UTF8, CH_UTF16LE),
1100 plato_output2.length / 2,
1101 "checking strlen_m_ext of round trip conversion of UTF16 latin charset greek to UTF8 and back again");
1103 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1104 CH_UTF8, CH_UTF8,
1105 plato_output.data, plato_output.length,
1106 (void *)&plato_output2.data, &plato_output2.length),
1107 "conversion of UTF8 to UTF8");
1108 torture_assert_data_blob_equal(tctx, plato_output2, plato_utf8,
1109 "conversion of UTF8 to UTF8");
1110 torture_assert_int_equal(tctx,
1111 strlen_m_ext_handle(iconv_handle,
1112 (const char *)plato_output.data,
1113 CH_UTF8, CH_UTF8),
1114 plato_output2.length,
1115 "checking strlen_m_ext of conversion of UTF8 to UTF8");
1116 return true;
1119 static bool test_plato_latin_cp850_utf8_handle(struct torture_context *tctx)
1121 struct smb_iconv_handle *iconv_handle;
1122 DATA_BLOB plato_latin_utf8 = base64_decode_data_blob(plato_latin_utf8_base64);
1123 DATA_BLOB plato_latin_utf16le = base64_decode_data_blob(plato_latin_utf16le_base64);
1124 DATA_BLOB plato_latin_output;
1125 DATA_BLOB plato_latin_output2;
1127 talloc_steal(tctx, plato_latin_utf8.data);
1128 talloc_steal(tctx, plato_latin_utf16le.data);
1130 iconv_handle = get_iconv_testing_handle(tctx, "CP850", "UTF8",
1131 lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
1132 torture_assert(tctx, iconv_handle, "creating iconv handle");
1134 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1135 CH_UTF8, CH_DOS,
1136 plato_latin_utf8.data, plato_latin_utf8.length,
1137 (void *)&plato_latin_output.data, &plato_latin_output.length) == false,
1138 "conversion of UTF8 latin charset greek to DOS charset CP850 should fail");
1140 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1141 CH_UTF8, CH_UNIX,
1142 plato_latin_utf8.data, plato_latin_utf8.length,
1143 (void *)&plato_latin_output.data, &plato_latin_output.length),
1144 "conversion of UTF16 latin charset greek to unix charset UTF8 failed");
1145 torture_assert_data_blob_equal(tctx, plato_latin_output, plato_latin_utf8, "conversion from UTF8 to (unix charset) UTF8 incorrect");
1147 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1148 CH_UTF8, CH_UTF8,
1149 plato_latin_utf8.data, plato_latin_utf8.length,
1150 (void *)&plato_latin_output.data, &plato_latin_output.length),
1151 "conversion of UTF16 latin charset greek to unix charset UTF8 failed");
1152 torture_assert_data_blob_equal(tctx, plato_latin_output, plato_latin_utf8, "conversion from UTF8 to UTF8 incorrect");
1154 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1155 CH_UTF16LE, CH_DOS,
1156 plato_latin_utf16le.data, plato_latin_utf16le.length,
1157 (void *)&plato_latin_output.data, &plato_latin_output.length) == false,
1158 "conversion of UTF16 latin charset greek to DOS charset CP850 should fail");
1160 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1161 CH_UTF16LE, CH_UNIX,
1162 plato_latin_utf16le.data, plato_latin_utf16le.length,
1163 (void *)&plato_latin_output.data, &plato_latin_output.length),
1164 "conversion of UTF16 latin charset greek to unix charset UTF8 failed");
1165 torture_assert_data_blob_equal(tctx, plato_latin_output, plato_latin_utf8, "conversion from UTF16LE to (unix charset) CP850 incorrect");
1167 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1168 CH_UTF16LE, CH_UTF8,
1169 plato_latin_utf16le.data, plato_latin_utf16le.length,
1170 (void *)&plato_latin_output.data, &plato_latin_output.length),
1171 "conversion of UTF16 latin charset greek to UTF8 failed");
1172 torture_assert_data_blob_equal(tctx, plato_latin_output, plato_latin_utf8, "conversion from UTF16LE to UTF8 incorrect");
1174 torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
1175 CH_UTF8, CH_UTF16LE,
1176 plato_latin_output.data, plato_latin_output.length,
1177 (void *)&plato_latin_output2.data, &plato_latin_output2.length),
1178 "round trip conversion of UTF16 latin charset greek to UTF8 and back again failed");
1179 torture_assert_data_blob_equal(tctx, plato_latin_output2, plato_latin_utf16le,
1180 "round trip conversion of UTF16 latin charset greek to UTF8 and back again failed");
1181 torture_assert_int_equal(tctx,
1182 strlen_m_ext_handle(iconv_handle,
1183 (const char *)plato_latin_output.data,
1184 CH_UTF8, CH_UTF16LE),
1185 plato_latin_output2.length / 2,
1186 "checking strlen_m_ext of round trip conversion of UTF16 latin charset greek to UTF8 and back again");
1187 return true;
1190 static bool test_gd_case_utf8_handle(struct torture_context *tctx)
1192 struct smb_iconv_handle *iconv_handle;
1193 DATA_BLOB gd_utf8 = base64_decode_data_blob(gd_utf8_base64);
1194 DATA_BLOB gd_utf8_upper = base64_decode_data_blob(gd_utf8_upper_base64);
1195 DATA_BLOB gd_utf8_lower = base64_decode_data_blob(gd_utf8_lower_base64);
1196 char *gd_lower, *gd_upper;
1197 talloc_steal(tctx, gd_utf8.data);
1199 iconv_handle = get_iconv_testing_handle(tctx, "ASCII", "UTF8",
1200 lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
1201 torture_assert(tctx, iconv_handle, "getting utf8 iconv handle");
1203 torture_assert(tctx,
1204 strhasupper_handle(iconv_handle, (const char *)gd_utf8.data),
1205 "GD's name has an upper case character");
1206 torture_assert(tctx,
1207 strhaslower_handle(iconv_handle, (const char *)gd_utf8.data),
1208 "GD's name has an lower case character");
1209 gd_lower = strlower_talloc_handle(iconv_handle, tctx, (const char *)gd_utf8.data);
1210 torture_assert(tctx, gd_lower, "failed to convert GD's name into lower case");
1211 torture_assert_data_blob_equal(tctx, data_blob_string_const(gd_lower), gd_utf8_lower,
1212 "convert GD's name into lower case");
1213 gd_upper = strupper_talloc_n_handle(iconv_handle, tctx, (const char *)gd_utf8.data, gd_utf8.length);
1214 torture_assert(tctx, gd_lower, "failed to convert GD's name into upper case");
1215 torture_assert_data_blob_equal(tctx, data_blob_string_const(gd_upper), gd_utf8_upper,
1216 "convert GD's name into upper case");
1218 torture_assert(tctx,
1219 strhasupper_handle(iconv_handle, gd_upper),
1220 "upper case name has an upper case character");
1221 torture_assert(tctx,
1222 strhaslower_handle(iconv_handle, gd_lower),
1223 "lower case name has an lower case character");
1224 torture_assert(tctx,
1225 strhasupper_handle(iconv_handle, gd_lower) == false,
1226 "lower case name has no upper case character");
1227 torture_assert(tctx,
1228 strhaslower_handle(iconv_handle, gd_upper) == false,
1229 "upper case name has no lower case character");
1231 torture_assert(tctx, strcasecmp_m_handle(iconv_handle, (const char *)gd_utf8.data,
1232 gd_upper) == 0,
1233 "case insensitive comparison orig/upper");
1234 torture_assert(tctx, strcasecmp_m_handle(iconv_handle, (const char *)gd_utf8.data,
1235 gd_lower) == 0,
1236 "case insensitive comparison orig/lower");
1237 torture_assert(tctx, strcasecmp_m_handle(iconv_handle, gd_upper,
1238 gd_lower) == 0,
1239 "case insensitive comparison upper/lower");
1241 /* This string isn't different in length upper/lower */
1242 torture_assert(tctx, strncasecmp_m_handle(iconv_handle, (const char *)gd_utf8.data,
1243 gd_upper, gd_utf8.length) == 0,
1244 "case insensitive comparison orig/upper");
1245 torture_assert(tctx, strncasecmp_m_handle(iconv_handle, (const char *)gd_utf8.data,
1246 gd_lower, gd_utf8.length) == 0,
1247 "case insensitive comparison orig/lower");
1248 torture_assert(tctx, strncasecmp_m_handle(iconv_handle, gd_upper,
1249 gd_lower, gd_utf8.length) == 0,
1250 "case insensitive comparison upper/lower");
1251 return true;
1254 static bool test_gd_case_cp850_handle(struct torture_context *tctx)
1256 struct smb_iconv_handle *iconv_handle;
1257 DATA_BLOB gd_cp850 = base64_decode_data_blob(gd_cp850_base64);
1258 DATA_BLOB gd_cp850_upper = base64_decode_data_blob(gd_cp850_upper_base64);
1259 DATA_BLOB gd_cp850_lower = base64_decode_data_blob(gd_cp850_lower_base64);
1260 char *gd_lower, *gd_upper;
1261 talloc_steal(tctx, gd_cp850.data);
1263 iconv_handle = get_iconv_testing_handle(tctx, "ASCII", "CP850",
1264 lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
1265 torture_assert(tctx, iconv_handle, "getting cp850 iconv handle");
1267 torture_assert(tctx,
1268 strhasupper_handle(iconv_handle, (const char *)gd_cp850.data),
1269 "GD's name has an upper case character");
1270 torture_assert(tctx,
1271 strhaslower_handle(iconv_handle, (const char *)gd_cp850.data),
1272 "GD's name has an lower case character");
1273 gd_lower = strlower_talloc_handle(iconv_handle, tctx, (const char *)gd_cp850.data);
1274 torture_assert(tctx, gd_lower, "failed to convert GD's name into lower case");
1275 torture_assert_data_blob_equal(tctx, data_blob_string_const(gd_lower), gd_cp850_lower,
1276 "convert GD's name into lower case");
1277 gd_upper = strupper_talloc_n_handle(iconv_handle, tctx, (const char *)gd_cp850.data, gd_cp850.length);
1278 torture_assert(tctx, gd_lower, "failed to convert GD's name into upper case");
1279 torture_assert_data_blob_equal(tctx, data_blob_string_const(gd_upper), gd_cp850_upper,
1280 "convert GD's name into upper case");
1282 torture_assert(tctx,
1283 strhasupper_handle(iconv_handle, gd_upper),
1284 "upper case name has an upper case character");
1285 torture_assert(tctx,
1286 strhaslower_handle(iconv_handle, gd_lower),
1287 "lower case name has an lower case character");
1288 torture_assert(tctx,
1289 strhasupper_handle(iconv_handle, gd_lower) == false,
1290 "lower case name has no upper case character");
1291 torture_assert(tctx,
1292 strhaslower_handle(iconv_handle, gd_upper) == false,
1293 "upper case name has no lower case character");
1295 torture_assert(tctx, strcasecmp_m_handle(iconv_handle, (const char *)gd_cp850.data,
1296 gd_upper) == 0,
1297 "case insensitive comparison orig/upper");
1298 torture_assert(tctx, strcasecmp_m_handle(iconv_handle, (const char *)gd_cp850.data,
1299 gd_lower) == 0,
1300 "case insensitive comparison orig/lower");
1301 torture_assert(tctx, strcasecmp_m_handle(iconv_handle, gd_upper,
1302 gd_lower) == 0,
1303 "case insensitive comparison upper/lower");
1305 /* This string isn't different in length upper/lower */
1306 torture_assert(tctx, strncasecmp_m_handle(iconv_handle, (const char *)gd_cp850.data,
1307 gd_upper, gd_cp850.length) == 0,
1308 "case insensitive comparison orig/upper");
1309 torture_assert(tctx, strncasecmp_m_handle(iconv_handle, (const char *)gd_cp850.data,
1310 gd_lower, gd_cp850.length) == 0,
1311 "case insensitive comparison orig/lower");
1312 torture_assert(tctx, strncasecmp_m_handle(iconv_handle, gd_upper,
1313 gd_lower, gd_cp850.length) == 0,
1314 "case insensitive comparison upper/lower");
1315 return true;
1318 static bool test_plato_case_utf8_handle(struct torture_context *tctx)
1320 struct smb_iconv_handle *iconv_handle;
1321 DATA_BLOB plato_utf8 = base64_decode_data_blob(plato_utf8_base64);
1322 char *plato_lower, *plato_upper;
1323 talloc_steal(tctx, plato_utf8.data);
1325 iconv_handle = get_iconv_testing_handle(tctx, "ASCII", "UTF8",
1326 lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
1327 torture_assert(tctx, iconv_handle, "getting utf8 iconv handle");
1329 torture_assert(tctx,
1330 strhasupper_handle(iconv_handle, (const char *)plato_utf8.data),
1331 "PLATO's apology has an upper case character");
1332 torture_assert(tctx,
1333 strhaslower_handle(iconv_handle, (const char *)plato_utf8.data),
1334 "PLATO's apology has an lower case character");
1335 plato_lower = strlower_talloc_handle(iconv_handle, tctx, (const char *)plato_utf8.data);
1336 torture_assert(tctx, plato_lower, "failed to convert PLATO's apology into lower case");
1337 plato_upper = strupper_talloc_n_handle(iconv_handle, tctx, (const char *)plato_utf8.data, plato_utf8.length);
1338 torture_assert(tctx, plato_lower, "failed to convert PLATO's apology into upper case");
1340 torture_assert(tctx,
1341 strhasupper_handle(iconv_handle, plato_upper),
1342 "upper case string has an upper case character");
1343 torture_assert(tctx,
1344 strhaslower_handle(iconv_handle, plato_lower),
1345 "lower case string has an lower case character");
1346 torture_assert(tctx,
1347 strhasupper_handle(iconv_handle, plato_lower) == false,
1348 "lower case string has no upper case character");
1349 torture_assert(tctx,
1350 strhaslower_handle(iconv_handle, plato_upper) == false,
1351 "upper case string has no lower case character");
1353 torture_assert(tctx, strcasecmp_m_handle(iconv_handle, (const char *)plato_utf8.data,
1354 plato_upper) == 0,
1355 "case insensitive comparison orig/upper");
1356 torture_assert(tctx, strcasecmp_m_handle(iconv_handle, (const char *)plato_utf8.data,
1357 plato_lower) == 0,
1358 "case insensitive comparison orig/lower");
1359 torture_assert(tctx, strcasecmp_m_handle(iconv_handle, plato_upper,
1360 plato_lower) == 0,
1361 "case insensitive comparison upper/lower");
1362 return true;
1365 static bool test_gd(struct torture_context *tctx)
1367 DATA_BLOB gd_utf8 = base64_decode_data_blob(gd_utf8_base64);
1368 DATA_BLOB gd_cp850 = base64_decode_data_blob(gd_cp850_base64);
1369 DATA_BLOB gd_iso8859_1 = base64_decode_data_blob(gd_iso8859_1_base64);
1370 DATA_BLOB gd_utf16le = base64_decode_data_blob(gd_utf16le_base64);
1371 DATA_BLOB gd_output;
1372 size_t saved_len;
1374 talloc_steal(tctx, gd_utf8.data);
1375 talloc_steal(tctx, gd_cp850.data);
1376 talloc_steal(tctx, gd_iso8859_1.data);
1377 talloc_steal(tctx, gd_utf16le.data);
1379 torture_assert(tctx, convert_string_talloc(tctx, CH_UTF8, CH_UTF8,
1380 gd_utf8.data, gd_utf8.length,
1381 (void *)&gd_output.data, &gd_output.length),
1382 "conversion from UTF8 to utf8 charset");
1383 saved_len = gd_output.length;
1385 torture_assert(tctx, convert_string_error(CH_UTF8, CH_UTF8,
1386 gd_utf8.data, gd_utf8.length,
1387 (void *)gd_output.data, gd_output.length,
1388 &gd_output.length),
1389 "conversion from UTF8 to utf8 charset");
1391 /* Short output handling confirmation */
1392 gd_output.length = 1;
1393 torture_assert(tctx, convert_string_error(CH_UTF8, CH_UTF8,
1394 gd_utf8.data, gd_utf8.length,
1395 (void *)gd_output.data, gd_output.length,
1396 &gd_output.length) == false,
1397 "conversion from UTF8 to any utf8 charset should fail due to too short");
1398 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to utf8 charset should fail E2BIG");
1399 torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
1400 torture_assert_data_blob_equal(tctx, gd_output, data_blob_string_const("G"), "conversion from UTF8 to utf8 charset incorrect");
1402 #if 0 /* This currently fails as we just copy like-for-like character conversions */
1403 /* Short output handling confirmation */
1404 gd_output.length = 2;
1405 torture_assert(tctx, convert_string_error(CH_UTF8, CH_UTF8,
1406 gd_utf8.data, gd_utf8.length,
1407 (void *)gd_output.data, gd_output.length,
1408 &gd_output.length) == false,
1409 "conversion from UTF8 to utf8 charset should fail due to too short");
1410 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to utf8 charset should fail E2BIG");
1411 torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
1413 /* Short input handling confirmation */
1414 gd_output.length = saved_len;
1415 torture_assert(tctx, convert_string_error(CH_UTF8, CH_UTF8,
1416 gd_utf8.data, 2,
1417 (void *)gd_output.data, gd_output.length,
1418 &gd_output.length) == false,
1419 "conversion from UTF8 to UTF8 should fail due to too short");
1420 torture_assert_errno_equal(tctx, EILSEQ, "conversion from short UTF8 to UTF8 should fail EINVAL");
1421 torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
1422 #endif
1424 /* Short output handling confirmation */
1425 gd_output.length = 1;
1426 torture_assert(tctx, convert_string_error(CH_UTF16LE, CH_UTF8,
1427 gd_utf16le.data, gd_utf16le.length,
1428 (void *)gd_output.data, gd_output.length,
1429 &gd_output.length) == false,
1430 "conversion from UTF16 to UTF8 should fail due to too short");
1431 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16 to UTF8 should fail E2BIG");
1432 torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
1433 torture_assert_data_blob_equal(tctx, gd_output, data_blob_string_const("G"), "conversion from UTF16 to UTF8 incorrect");
1435 /* Short output handling confirmation */
1436 gd_output.length = 3;
1437 torture_assert(tctx, convert_string_error(CH_UTF16LE, CH_UTF8,
1438 gd_utf16le.data, gd_utf16le.length,
1439 (void *)gd_output.data, gd_output.length,
1440 &gd_output.length) == false,
1441 "conversion from UTF16 to UTF8 should fail due to too short");
1442 torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16 to UTF8 should fail E2BIG");
1443 torture_assert_int_equal(tctx, gd_output.length, 3, "Should get 3 bytes output for UTF8");
1445 /* Short input handling confirmation */
1446 gd_output.length = saved_len;
1447 torture_assert(tctx, convert_string_error(CH_UTF16LE, CH_UTF8,
1448 gd_utf16le.data, 3,
1449 (void *)gd_output.data, gd_output.length,
1450 &gd_output.length) == false,
1451 "conversion from UTF16 to UTF8 should fail due to too short");
1452 torture_assert_errno_equal(tctx, EINVAL, "conversion from short UTF16 to UTF8 should fail EINVAL");
1453 torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
1455 return true;
1458 static bool test_plato(struct torture_context *tctx)
1460 DATA_BLOB plato_utf8 = base64_decode_data_blob(plato_utf8_base64);
1461 DATA_BLOB plato_utf16le = base64_decode_data_blob(plato_utf16le_base64);
1462 DATA_BLOB plato_output;
1463 DATA_BLOB plato_output2;
1465 talloc_steal(tctx, plato_utf8.data);
1466 talloc_steal(tctx, plato_utf16le.data);
1468 torture_assert(tctx, convert_string_talloc(tctx,
1469 CH_UTF8, CH_UTF16LE,
1470 plato_utf8.data, plato_utf8.length,
1471 (void *)&plato_output.data, &plato_output.length),
1472 "conversion of UTF8 ancient greek to UTF16 failed");
1473 torture_assert_data_blob_equal(tctx, plato_output, plato_utf16le, "conversion from UTF8 to UTF16LE incorrect");
1475 torture_assert_int_equal(tctx,
1476 strlen_m_ext((const char *)plato_utf8.data,
1477 CH_UTF8, CH_UTF16LE),
1478 plato_output.length / 2,
1479 "checking strlen_m_ext of conversion of UTF8 to UTF16LE");
1481 memset(plato_output.data, '\0', plato_output.length);
1482 torture_assert(tctx, convert_string_error(CH_UTF8, CH_UTF16LE,
1483 plato_utf8.data, plato_utf8.length,
1484 (void *)plato_output.data, plato_output.length,
1485 &plato_output.length),
1486 "conversion of UTF8 ancient greek to UTF16 failed");
1487 torture_assert_data_blob_equal(tctx, plato_output, plato_utf16le, "conversion from UTF8 to UTF16LE incorrect");
1489 torture_assert(tctx, convert_string_talloc(tctx,
1490 CH_UTF16LE, CH_UTF8,
1491 plato_output.data, plato_output.length,
1492 (void *)&plato_output2.data, &plato_output2.length),
1493 "conversion of UTF8 ancient greek to UTF16 failed");
1494 torture_assert_data_blob_equal(tctx, plato_output2, plato_utf8, "conversion from UTF8 to UTF16LE incorrect");
1496 memset(plato_output2.data, '\0', plato_output2.length);
1497 torture_assert(tctx, convert_string_error(CH_UTF16LE, CH_UTF8,
1498 plato_output.data, plato_output.length,
1499 (void *)plato_output2.data, plato_output2.length, &plato_output2.length),
1500 "conversion of UTF8 ancient greek to UTF16 failed");
1501 torture_assert_data_blob_equal(tctx, plato_output2, plato_utf8, "conversion from UTF8 to UTF16LE incorrect");
1503 torture_assert(tctx, convert_string_talloc(tctx,
1504 CH_UTF8, CH_UTF8,
1505 plato_utf8.data, plato_utf8.length,
1506 (void *)&plato_output.data, &plato_output.length),
1507 "conversion of UTF8 to UTF8");
1508 torture_assert_data_blob_equal(tctx, plato_output, plato_utf8,
1509 "conversion of UTF8 to UTF8");
1510 torture_assert_int_equal(tctx,
1511 strlen_m_ext((const char *)plato_utf8.data,
1512 CH_UTF8, CH_UTF8),
1513 plato_output.length,
1514 "checking strlen_m_ext of conversion of UTF8 to UTF8");
1515 memset(plato_output.data, '\0', plato_output.length);
1516 torture_assert(tctx, convert_string_error(CH_UTF8, CH_UTF8,
1517 plato_utf8.data, plato_utf8.length,
1518 (void *)plato_output.data, plato_output.length,
1519 &plato_output.length),
1520 "conversion of UTF8 to UTF8");
1521 torture_assert_data_blob_equal(tctx, plato_output, plato_utf8,
1522 "conversion of UTF8 to UTF8");
1524 memset(plato_output.data, '\0', plato_output.length);
1525 torture_assert(tctx, convert_string_error(CH_UTF8, CH_DOS,
1526 plato_utf8.data, plato_utf8.length,
1527 (void *)plato_output.data, plato_output.length,
1528 &plato_output.length) == false,
1529 "conversion of UTF8 to any dos charset should fail");
1530 torture_assert_errno_equal(tctx, EILSEQ, "conversion of UTF16 ancient greek to any DOS charset should fail EILSEQ");
1532 torture_assert(tctx, convert_string_talloc(tctx,
1533 CH_UTF8, CH_DOS,
1534 plato_utf8.data, plato_utf8.length,
1535 (void *)&plato_output.data, &plato_output.length) == false,
1536 "conversion of UTF8 ancient greek to any DOS charset should fail");
1538 /* Allocate only enough space for a partial conversion */
1539 plato_output = data_blob_talloc(tctx, NULL, 9);
1540 torture_assert(tctx, convert_string_error(CH_UTF16LE, CH_UTF8,
1541 plato_utf16le.data, plato_utf16le.length,
1542 (void *)plato_output.data, plato_output.length,
1543 &plato_output.length) == false,
1544 "conversion of UTF16 ancient greek to UTF8 should fail, not enough space");
1545 torture_assert_errno_equal(tctx, E2BIG, "conversion of UTF16 ancient greek to UTF8 should fail, not enough space");
1546 torture_assert_int_equal(tctx, plato_output.length, 8,
1547 "conversion of UTF16 ancient greek to UTF8 should stop on multibyte boundary");
1549 plato_output = data_blob_talloc(tctx, NULL, 2);
1550 torture_assert(tctx, convert_string_error(CH_UTF16LE, CH_UTF8,
1551 plato_utf16le.data, plato_utf16le.length,
1552 (void *)plato_output.data, plato_output.length,
1553 &plato_output.length) == false,
1554 "conversion of UTF16 ancient greek to UTF8 should fail, not enough space");
1555 torture_assert_errno_equal(tctx, E2BIG, "conversion of UTF16 ancient greek to UTF8 should fail, not enough space");
1556 torture_assert_int_equal(tctx, plato_output.length, 0,
1557 "conversion of UTF16 ancient greek to UTF8 should stop on multibyte boundary");
1560 return true;
1563 static bool test_plato_latin(struct torture_context *tctx)
1565 DATA_BLOB plato_latin_utf8 = base64_decode_data_blob(plato_latin_utf8_base64);
1566 DATA_BLOB plato_latin_utf16le = base64_decode_data_blob(plato_latin_utf16le_base64);
1567 DATA_BLOB plato_latin_output;
1569 talloc_steal(tctx, plato_latin_utf8.data);
1570 talloc_steal(tctx, plato_latin_utf16le.data);
1572 torture_assert(tctx, convert_string_talloc(tctx,
1573 CH_UTF16LE, CH_UTF8,
1574 plato_latin_utf16le.data, plato_latin_utf16le.length,
1575 (void *)&plato_latin_output.data, &plato_latin_output.length),
1576 "conversion of UTF16 latin charset greek to unix charset UTF8 failed");
1577 torture_assert_data_blob_equal(tctx, plato_latin_output, plato_latin_utf8, "conversion from UTF16 to UTF8 incorrect");
1579 torture_assert_int_equal(tctx,
1580 strlen_m_ext((const char *)plato_latin_output.data,
1581 CH_UTF8, CH_UTF16LE),
1582 plato_latin_utf16le.length / 2,
1583 "checking strlen_m_ext UTF16 latin charset greek to UTF8");
1584 torture_assert(tctx, convert_string_talloc(tctx,
1585 CH_UTF8, CH_UTF16LE,
1586 plato_latin_utf8.data, plato_latin_utf8.length,
1587 (void *)&plato_latin_output.data, &plato_latin_output.length),
1588 "conversion of UTF16 latin charset greek to UTF16LE failed");
1589 torture_assert_data_blob_equal(tctx, plato_latin_output, plato_latin_utf16le, "conversion from UTF8 to UTF16LE incorrect");
1591 return true;
1594 static bool test_gd_case(struct torture_context *tctx)
1596 DATA_BLOB gd_utf8 = base64_decode_data_blob(gd_utf8_base64);
1597 char *gd_unix;
1598 size_t gd_size;
1599 char *gd_lower, *gd_upper;
1600 talloc_steal(tctx, gd_utf8.data);
1602 torture_assert(tctx, convert_string_talloc(tctx, CH_UTF8, CH_UNIX,
1603 gd_utf8.data, gd_utf8.length,
1604 (void *)&gd_unix, &gd_size),
1605 "conversion of unix charset to UTF8");
1607 gd_lower = strlower_talloc(tctx, gd_unix);
1608 torture_assert(tctx, gd_lower, "failed to convert GD's name into lower case");
1609 gd_upper = strupper_talloc_n(tctx, gd_unix, gd_size);
1610 torture_assert(tctx, gd_lower, "failed to convert GD's name into upper case");
1612 torture_assert(tctx,
1613 strhasupper(gd_unix),
1614 "GD's name has an upper case character");
1615 torture_assert(tctx,
1616 strhaslower(gd_unix),
1617 "GD's name has an lower case character");
1618 torture_assert(tctx,
1619 strhasupper(gd_upper),
1620 "upper case name has an upper case character");
1621 torture_assert(tctx,
1622 strhaslower(gd_lower),
1623 "lower case name has an lower case character");
1624 torture_assert(tctx,
1625 strhasupper(gd_lower) == false,
1626 "lower case name has no upper case character");
1627 torture_assert(tctx,
1628 strhaslower(gd_upper) == false,
1629 "upper case name has no lower case character");
1631 torture_assert(tctx, strcasecmp_m(gd_unix,
1632 gd_upper) == 0,
1633 "case insensitive comparison orig/upper");
1634 torture_assert(tctx, strcasecmp_m(gd_unix,
1635 gd_lower) == 0,
1636 "case insensitive comparison orig/lower");
1637 torture_assert(tctx, strcasecmp_m(gd_upper,
1638 gd_lower) == 0,
1639 "case insensitive comparison upper/lower");
1641 /* This string isn't different in length upper/lower, but just check the first 5 chars */
1642 torture_assert(tctx, strncasecmp_m(gd_unix,
1643 gd_upper, 5) == 0,
1644 "case insensitive comparison orig/upper");
1645 torture_assert(tctx, strncasecmp_m(gd_unix,
1646 gd_lower, 5) == 0,
1647 "case insensitive comparison orig/lower");
1648 torture_assert(tctx, strncasecmp_m(gd_upper,
1649 gd_lower, 5) == 0,
1650 "case insensitive comparison upper/lower");
1651 return true;
1654 static bool test_plato_case(struct torture_context *tctx)
1656 DATA_BLOB plato_utf8 = base64_decode_data_blob(plato_utf8_base64);
1657 char *plato_unix;
1658 size_t plato_length;
1659 char *plato_lower, *plato_upper;
1660 talloc_steal(tctx, plato_utf8.data);
1662 torture_assert(tctx, convert_string_talloc(tctx, CH_UTF8, CH_UNIX,
1663 plato_utf8.data, plato_utf8.length,
1664 (void *)&plato_unix, &plato_length),
1665 "conversion of unix charset to UTF8");
1667 torture_assert(tctx,
1668 strhasupper(plato_unix),
1669 "PLATO's apology has an upper case character");
1670 torture_assert(tctx,
1671 strhaslower(plato_unix),
1672 "PLATO's apology has an lower case character");
1673 plato_lower = strlower_talloc(tctx, plato_unix);
1674 torture_assert(tctx, plato_lower, "failed to convert PLATO's apology into lower case");
1675 plato_upper = strupper_talloc_n(tctx, plato_unix, plato_utf8.length);
1676 torture_assert(tctx, plato_lower, "failed to convert PLATO's apology into upper case");
1678 torture_assert(tctx,
1679 strhasupper(plato_upper),
1680 "upper case string has an upper case character");
1681 torture_assert(tctx,
1682 strhaslower(plato_lower),
1683 "lower case string has an lower case character");
1684 torture_assert(tctx,
1685 strhasupper(plato_lower) == false,
1686 "lower case string has no upper case character");
1687 torture_assert(tctx,
1688 strhaslower(plato_upper) == false,
1689 "upper case string has no lower case character");
1691 torture_assert(tctx, strcasecmp_m(plato_unix,
1692 plato_upper) == 0,
1693 "case insensitive comparison orig/upper");
1694 torture_assert(tctx, strcasecmp_m(plato_unix,
1695 plato_lower) == 0,
1696 "case insensitive comparison orig/lower");
1697 torture_assert(tctx, strcasecmp_m(plato_upper,
1698 plato_lower) == 0,
1699 "case insensitive comparison upper/lower");
1700 return true;
1703 struct torture_suite *torture_local_convert_string_handle(TALLOC_CTX *mem_ctx)
1705 struct torture_suite *suite = torture_suite_create(mem_ctx, "convert_string_handle");
1707 torture_suite_add_simple_test(suite, "gd_ascii", test_gd_ascii_handle);
1708 torture_suite_add_simple_test(suite, "gd_minus_1", test_gd_minus_1_handle);
1709 torture_suite_add_simple_test(suite, "gd_iso8859_cp850", test_gd_iso8859_cp850_handle);
1710 torture_suite_add_simple_test(suite, "plato_english_iso8859_cp850", test_plato_english_iso8859_cp850_handle);
1711 torture_suite_add_simple_test(suite, "plato_english_minus_1", test_plato_english_minus_1_handle);
1712 torture_suite_add_simple_test(suite, "plato_cp850_utf8", test_plato_cp850_utf8_handle);
1713 torture_suite_add_simple_test(suite, "plato_minus_1", test_plato_minus_1_handle);
1714 torture_suite_add_simple_test(suite, "plato_latin_cp850_utf8", test_plato_latin_cp850_utf8_handle);
1715 return suite;
1718 struct torture_suite *torture_local_string_case_handle(TALLOC_CTX *mem_ctx)
1720 struct torture_suite *suite = torture_suite_create(mem_ctx, "string_case_handle");
1722 torture_suite_add_simple_test(suite, "gd_case_utf8", test_gd_case_utf8_handle);
1723 torture_suite_add_simple_test(suite, "gd_case_cp850", test_gd_case_cp850_handle);
1724 torture_suite_add_simple_test(suite, "plato_case_utf8", test_plato_case_utf8_handle);
1725 return suite;
1728 struct torture_suite *torture_local_convert_string(TALLOC_CTX *mem_ctx)
1730 struct torture_suite *suite = torture_suite_create(mem_ctx, "convert_string");
1732 torture_suite_add_simple_test(suite, "gd", test_gd);
1733 torture_suite_add_simple_test(suite, "plato", test_plato);
1734 torture_suite_add_simple_test(suite, "plato_latin", test_plato_latin);
1735 return suite;
1738 struct torture_suite *torture_local_string_case(TALLOC_CTX *mem_ctx)
1740 struct torture_suite *suite = torture_suite_create(mem_ctx, "string_case_handle");
1742 torture_suite_add_simple_test(suite, "gd_case", test_gd_case);
1743 torture_suite_add_simple_test(suite, "plato_case", test_plato_case);
1744 return suite;