The branch, master has been updated via 43e364e lib/util/charset Add tests for convert_string_talloc_handle() via a64958a lib/util Move base64 functions into lib/util/base64.c via 48d0abe s3:lib make lazy_initialize_conv() static via c395209 lib/util/charset Remove pointless static bool initialised from fbd0ff6 s3: try to fix the build on some non-linux buildfarm machines.
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 43e364e61bc232e167ed1a18de037f8a278c8c24 Author: Andrew Bartlett <abart...@samba.org> Date: Wed Mar 30 17:49:30 2011 +1100 lib/util/charset Add tests for convert_string_talloc_handle() Andrew Bartlett Autobuild-User: Andrew Bartlett <abart...@samba.org> Autobuild-Date: Wed Mar 30 13:02:47 CEST 2011 on sn-devel-104 commit a64958a8805b6ef1758293697e63309d3ddbe4ae Author: Andrew Bartlett <abart...@samba.org> Date: Wed Mar 30 17:49:01 2011 +1100 lib/util Move base64 functions into lib/util/base64.c Andrew Bartlett commit 48d0abe0b50b4e0414f5dcb46aae2a4b5bfaac7e Author: Andrew Bartlett <abart...@samba.org> Date: Tue Mar 29 13:21:52 2011 +1100 s3:lib make lazy_initialize_conv() static commit c3952097910bb34ac8c00b1a23261fea7ce56bfc Author: Andrew Bartlett <abart...@samba.org> Date: Tue Mar 29 09:45:22 2011 +1100 lib/util/charset Remove pointless static bool initialised ----------------------------------------------------------------------- Summary of changes: lib/util/base64.c | 141 +++++++++++ lib/util/charset/charset.h | 4 + lib/util/charset/codepoints.c | 14 +- lib/util/charset/tests/convert_string.c | 418 +++++++++++++++++++++++++++++++ lib/util/util.h | 13 + lib/util/util_str.c | 2 - lib/util/wscript_build | 2 +- source3/Makefile.in | 2 +- source3/include/proto.h | 4 - source3/lib/charcnv.c | 2 +- source3/lib/util_str.c | 115 --------- source4/torture/local/local.c | 1 + source4/torture/local/wscript_build | 1 + source4/utils/ntlm_auth.c | 31 +--- 14 files changed, 592 insertions(+), 158 deletions(-) create mode 100644 lib/util/base64.c create mode 100644 lib/util/charset/tests/convert_string.c Changeset truncated at 500 lines: diff --git a/lib/util/base64.c b/lib/util/base64.c new file mode 100644 index 0000000..19ce2d1 --- /dev/null +++ b/lib/util/base64.c @@ -0,0 +1,141 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + + Copyright (C) Andrew Tridgell 1992-2001 + Copyright (C) Simo Sorce 2001-2002 + Copyright (C) Martin Pool 2003 + Copyright (C) James Peach 2006 + Copyright (C) Jeremy Allison 1992-2007 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "includes.h" + +static const char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +/** + * Decode a base64 string into a DATA_BLOB - simple and slow algorithm + **/ +_PUBLIC_ DATA_BLOB base64_decode_data_blob(const char *s) +{ + int bit_offset, byte_offset, idx, i, n; + DATA_BLOB decoded = data_blob(s, strlen(s)+1); + unsigned char *d = decoded.data; + char *p; + + n=i=0; + + while (*s && (p=strchr_m(b64,*s))) { + idx = (int)(p - b64); + byte_offset = (i*6)/8; + bit_offset = (i*6)%8; + d[byte_offset] &= ~((1<<(8-bit_offset))-1); + if (bit_offset < 3) { + d[byte_offset] |= (idx << (2-bit_offset)); + n = byte_offset+1; + } else { + d[byte_offset] |= (idx >> (bit_offset-2)); + d[byte_offset+1] = 0; + d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF; + n = byte_offset+2; + } + s++; i++; + } + + if ((n > 0) && (*s == '=')) { + n -= 1; + } + + /* fix up length */ + decoded.length = n; + return decoded; +} + +/** + * Decode a base64 string in-place - wrapper for the above + **/ +_PUBLIC_ void base64_decode_inplace(char *s) +{ + DATA_BLOB decoded = base64_decode_data_blob(s); + + if ( decoded.length != 0 ) { + memcpy(s, decoded.data, decoded.length); + + /* null terminate */ + s[decoded.length] = '\0'; + } else { + *s = '\0'; + } + + data_blob_free(&decoded); +} + +/** + * Encode a base64 string into a talloc()ed string caller to free. + * + * From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c + * with adjustments + **/ + +_PUBLIC_ char *base64_encode_data_blob(TALLOC_CTX *mem_ctx, DATA_BLOB data) +{ + int bits = 0; + int char_count = 0; + size_t out_cnt, len, output_len; + char *result; + + if (!data.length || !data.data) + return NULL; + + out_cnt = 0; + len = data.length; + output_len = data.length * 2 + 4; /* Account for closing bytes. 4 is + * random but should be enough for + * the = and \0 */ + result = talloc_array(mem_ctx, char, output_len); /* get us plenty of space */ + SMB_ASSERT(result != NULL); + + while (len--) { + int c = (unsigned char) *(data.data++); + bits += c; + char_count++; + if (char_count == 3) { + result[out_cnt++] = b64[bits >> 18]; + result[out_cnt++] = b64[(bits >> 12) & 0x3f]; + result[out_cnt++] = b64[(bits >> 6) & 0x3f]; + result[out_cnt++] = b64[bits & 0x3f]; + bits = 0; + char_count = 0; + } else { + bits <<= 8; + } + } + if (char_count != 0) { + bits <<= 16 - (8 * char_count); + result[out_cnt++] = b64[bits >> 18]; + result[out_cnt++] = b64[(bits >> 12) & 0x3f]; + if (char_count == 1) { + result[out_cnt++] = '='; + result[out_cnt++] = '='; + } else { + result[out_cnt++] = b64[(bits >> 6) & 0x3f]; + result[out_cnt++] = '='; + } + } + result[out_cnt] = '\0'; /* terminate */ + return result; +} + diff --git a/lib/util/charset/charset.h b/lib/util/charset/charset.h index 30ebcd5..b17ceab 100644 --- a/lib/util/charset/charset.h +++ b/lib/util/charset/charset.h @@ -161,6 +161,10 @@ ssize_t iconv_talloc(TALLOC_CTX *mem_ctx, extern struct smb_iconv_handle *global_iconv_handle; struct smb_iconv_handle *get_iconv_handle(void); +struct smb_iconv_handle *get_iconv_testing_handle(TALLOC_CTX *mem_ctx, + const char *dos_charset, + const char *unix_charset, + const char *display_charset); smb_iconv_t get_conv_handle(struct smb_iconv_handle *ic, charset_t from, charset_t to); const char *charset_name(struct smb_iconv_handle *ic, charset_t ch); diff --git a/lib/util/charset/codepoints.c b/lib/util/charset/codepoints.c index 62a80a3..cd54420 100644 --- a/lib/util/charset/codepoints.c +++ b/lib/util/charset/codepoints.c @@ -172,6 +172,15 @@ struct smb_iconv_handle *get_iconv_handle(void) return global_iconv_handle; } +struct smb_iconv_handle *get_iconv_testing_handle(TALLOC_CTX *mem_ctx, + const char *dos_charset, + const char *unix_charset, + const char *display_charset) +{ + return smb_iconv_handle_reinit(mem_ctx, + dos_charset, unix_charset, display_charset, true, NULL); +} + /** * Return the name of a charset to give to iconv(). **/ @@ -296,11 +305,6 @@ smb_iconv_t get_conv_handle(struct smb_iconv_handle *ic, charset_t from, charset_t to) { const char *n1, *n2; - static bool initialised; - - if (initialised == false) { - initialised = true; - } if (ic->conv_handles[from][to]) { return ic->conv_handles[from][to]; diff --git a/lib/util/charset/tests/convert_string.c b/lib/util/charset/tests/convert_string.c new file mode 100644 index 0000000..d57491c --- /dev/null +++ b/lib/util/charset/tests/convert_string.c @@ -0,0 +1,418 @@ +/* + Unix SMB/CIFS implementation. + test suite for the charcnv functions + + Copyright (C) Andrew Bartlett 2011 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "includes.h" +#include "torture/torture.h" +#include "lib/util/charset/charset.h" + +/* The text below is in ancient and a latin charset transliteration of + * greek, and an english translation. It from Apology by Plato and sourced from + * http://en.wikipedia.org/w/index.php?title=Ancient_Greek&oldid=421361065#Example_text + */ + +const char *plato_english_ascii = + "What you, men of Athens, have learned from my accusers, I do not" + " know: but I, for my part, nearly forgot who I was thanks to them since" + " they spoke so persuasively. And yet, of the truth, they have spoken," + " one might say, nothing at all."; + +const char *plato_english_utf16le_base64 = + "VwBoAGEAdAAgAHkAbwB1ACwAIABtAGUAbgAgAG8AZgAgAEEAdABoAGUAbgBzACwAIABoAGEAdgBl" + "ACAAbABlAGEAcgBuAGUAZAAgAGYAcgBvAG0AIABtAHkAIABhAGMAYwB1AHMAZQByAHMALAAgAEkA" + "IABkAG8AIABuAG8AdAAgAGsAbgBvAHcAOgAgAGIAdQB0ACAASQAsACAAZgBvAHIAIABtAHkAIABw" + "AGEAcgB0ACwAIABuAGUAYQByAGwAeQAgAGYAbwByAGcAbwB0ACAAdwBoAG8AIABJACAAdwBhAHMA" + "IAB0AGgAYQBuAGsAcwAgAHQAbwAgAHQAaABlAG0AIABzAGkAbgBjAGUAIAB0AGgAZQB5ACAAcwBw" + "AG8AawBlACAAcwBvACAAcABlAHIAcwB1AGEAcwBpAHYAZQBsAHkALgAgAEEAbgBkACAAeQBlAHQA" + "LAAgAG8AZgAgAHQAaABlACAAdAByAHUAdABoACwAIAB0AGgAZQB5ACAAaABhAHYAZQAgAHMAcABv" + "AGsAZQBuACwAIABvAG4AZQAgAG0AaQBnAGgAdAAgAHMAYQB5ACwAIABuAG8AdABoAGkAbgBnACAA" + "YQB0ACAAYQBsAGwALgA="; + +static const char *plato_utf8_base64 = + "4b2Nz4TOuSDOvOG9ss69IOG9kc68zrXhv5bPgiwg4b2mIOG8hM69zrTPgc61z4IgzobOuM63zr3O" + "seG/ls6/zrksIM+AzrXPgM+Mzr3OuM6xz4TOtSDhvZHPgOG9uCDPhOG/ts69IOG8kM684b+2zr0g" + "zrrOsc+EzrfOs8+Mz4HPic69LCDOv+G9kM66IM6/4by2zrTOsTog4byQzrPhvbwgzrQnIM6/4b2W" + "zr0gzrrOseG9tiDOseG9kM+E4b24z4Ig4b2Rz4AnIM6x4b2Qz4Thv7bOvSDhvYDOu86vzrPOv8+F" + "IOG8kM68zrHPhc+Ezr/hv6Yg4byQz4DOtc67zrHOuM+MzrzOt869LCDOv+G9lc+Ez4kgz4DOuc64" + "zrHOveG/ts+CIOG8lM67zrXOs86/zr0uIM6azrHOr8+Ezr/OuSDhvIDOu863zrjOrc+CIM6zzrUg" + "4b2hz4Ig4byUz4DOv8+CIM614bywz4DOteG/ls69IM6/4b2QzrThvbLOvSDOteG8sM+Bzq7Ous6x" + "z4POuc69Lg=="; + +static const char *plato_utf16le_base64 = + "TR/EA7kDIAC8A3IfvQMgAFEfvAO1A9YfwgMsACAAZh8gAAQfvQO0A8EDtQPCAyAAhgO4A7cDvQOx" + "A9YfvwO5AywAIADAA7UDwAPMA70DuAOxA8QDtQMgAFEfwAN4HyAAxAP2H70DIAAQH7wD9h+9AyAA" + "ugOxA8QDtwOzA8wDwQPJA70DLAAgAL8DUB+6AyAAvwM2H7QDsQM6ACAAEB+zA3wfIAC0AycAIAC/" + "A1YfvQMgALoDsQN2HyAAsQNQH8QDeB/CAyAAUR/AAycAIACxA1AfxAP2H70DIABAH7sDrwOzA78D" + "xQMgABAfvAOxA8UDxAO/A+YfIAAQH8ADtQO7A7EDuAPMA7wDtwO9AywAIAC/A1UfxAPJAyAAwAO5" + "A7gDsQO9A/YfwgMgABQfuwO1A7MDvwO9Ay4AIACaA7EDrwPEA78DuQMgAAAfuwO3A7gDrQPCAyAA" + "swO1AyAAYR/CAyAAFB/AA78DwgMgALUDMB/AA7UD1h+9AyAAvwNQH7QDch+9AyAAtQMwH8EDrgO6" + "A7EDwwO5A70DLgA="; + +static const char *plato_latin_utf8_base64 = + "SMOzdGkgbcOobiBodW1lw65zLCDDtCDDoW5kcmVzIEF0aMSTbmHDrm9pLCBwZXDDs250aGF0ZSBo" + "dXDDsiB0w7RuIGVtw7RuIGthdMSTZ8OzcsWNbiwgb3VrIG/DrmRhOiBlZ+G5kSBkJyBvw7tuIGth" + "w6wgYXV0w7JzIGh1cCcgYXV0xY1uIG9sw61nb3UgZW1hdXRvw7sgZXBlbGF0aMOzbcSTbiwgaG/D" + "unTFjSBwaXRoYW7DtHMgw6lsZWdvbi4gS2HDrXRvaSBhbMSTdGjDqXMgZ2UgaMWNcyDDqXBvcyBl" + "aXBlw65uIG91ZMOobiBlaXLhuJdrYXNpbi4="; + +static const char *plato_latin_utf16le_base64 = + "SADzAHQAaQAgAG0A6ABuACAAaAB1AG0AZQDuAHMALAAgAPQAIADhAG4AZAByAGUAcwAgAEEAdABo" + "ABMBbgBhAO4AbwBpACwAIABwAGUAcADzAG4AdABoAGEAdABlACAAaAB1AHAA8gAgAHQA9ABuACAA" + "ZQBtAPQAbgAgAGsAYQB0ABMBZwDzAHIATQFuACwAIABvAHUAawAgAG8A7gBkAGEAOgAgAGUAZwBR" + "HiAAZAAnACAAbwD7AG4AIABrAGEA7AAgAGEAdQB0APIAcwAgAGgAdQBwACcAIABhAHUAdABNAW4A" + "IABvAGwA7QBnAG8AdQAgAGUAbQBhAHUAdABvAPsAIABlAHAAZQBsAGEAdABoAPMAbQATAW4ALAAg" + "AGgAbwD6AHQATQEgAHAAaQB0AGgAYQBuAPQAcwAgAOkAbABlAGcAbwBuAC4AIABLAGEA7QB0AG8A" + "aQAgAGEAbAATAXQAaADpAHMAIABnAGUAIABoAE0BcwAgAOkAcABvAHMAIABlAGkAcABlAO4AbgAg" + "AG8AdQBkAOgAbgAgAGUAaQByABceawBhAHMAaQBuAC4A"; + +static const char *gd_utf8_base64 = "R8O8bnRoZXIgRGVzY2huZXI="; +static const char *gd_cp850_base64 = "R4FudGhlciBEZXNjaG5lcg=="; +static const char *gd_iso8859_1_base64 = "R/xudGhlciBEZXNjaG5lcg=="; +static const char *gd_utf16le_base64 = "RwD8AG4AdABoAGUAcgAgAEQAZQBzAGMAaABuAGUAcgA="; + +static bool test_gd_iso8859_cp850(struct torture_context *tctx) +{ + struct smb_iconv_handle *iconv_handle; + DATA_BLOB gd_utf8 = base64_decode_data_blob(gd_utf8_base64); + DATA_BLOB gd_cp850 = base64_decode_data_blob(gd_cp850_base64); + DATA_BLOB gd_iso8859_1 = base64_decode_data_blob(gd_iso8859_1_base64); + DATA_BLOB gd_utf16le = base64_decode_data_blob(gd_utf16le_base64); + DATA_BLOB gd_output; + DATA_BLOB gd_output2; + + talloc_steal(tctx, gd_utf8.data); + talloc_steal(tctx, gd_cp850.data); + talloc_steal(tctx, gd_iso8859_1.data); + talloc_steal(tctx, gd_utf16le.data); + + iconv_handle = get_iconv_testing_handle(tctx, "ISO8859-1", "CP850", "UTF8"); + torture_assert(tctx, iconv_handle, "getting iconv handle"); + + torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, + CH_UTF8, CH_DOS, + gd_utf8.data, gd_utf8.length, + (void *)&gd_output.data, &gd_output.length), + "conversion from UTF8 to (dos charset) ISO8859-1"); + torture_assert_data_blob_equal(tctx, gd_output, gd_iso8859_1, "conversion from UTF8 to (dos charset) ISO8859-1 incorrect"); + + torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, + CH_UTF8, CH_UNIX, + gd_utf8.data, gd_utf8.length, + (void *)&gd_output.data, &gd_output.length), + "conversion from UTF8 to (unix charset) CP850"); + torture_assert_data_blob_equal(tctx, gd_output, gd_cp850, "conversion from UTF8 to (unix charset) CP850 incorrect"); + + torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, + CH_UTF8, CH_DISPLAY, + gd_utf8.data, gd_utf8.length, + (void *)&gd_output.data, &gd_output.length), + "conversion from UTF8 to (display charset) UTF8"); + torture_assert_data_blob_equal(tctx, gd_output, gd_utf8, "conversion from UTF8 to (display charset) UTF8 incorrect"); + + torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, + CH_UTF16LE, CH_DOS, + gd_utf16le.data, gd_utf16le.length, + (void *)&gd_output.data, &gd_output.length), + "conversion from UTF16LE to (dos charset) ISO8859-1"); + torture_assert_data_blob_equal(tctx, gd_output, gd_iso8859_1, "conversion from UTF16LE to (dos charset) ISO8859-1 incorrect"); + + torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, + CH_DOS, CH_UTF16LE, + gd_output.data, gd_output.length, + (void *)&gd_output2.data, &gd_output2.length), + "round trip conversion from (dos charset) ISO8859-1 back to UTF16LE"); + torture_assert_data_blob_equal(tctx, gd_output2, gd_utf16le, "round trip conversion from (dos charset) ISO8859-1 back to UTF16LE"); + + torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, + CH_UTF16LE, CH_UNIX, + gd_utf16le.data, gd_utf16le.length, + (void *)&gd_output.data, &gd_output.length), + "conversion from UTF16LE to (unix charset) CP850"); + torture_assert_data_blob_equal(tctx, gd_output, gd_cp850, "conversion from UTF16LE to (unix charset) CP850 incorrect"); + + torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, + CH_UTF16LE, CH_DISPLAY, + gd_utf16le.data, gd_utf16le.length, + (void *)&gd_output.data, &gd_output.length), + "conversion from UTF16LE to (display charset) UTF8"); + torture_assert_data_blob_equal(tctx, gd_output, gd_utf8, "conversion from UTF16LE to (display charset) UTF8 incorrect"); + + torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, + CH_DOS, CH_DOS, + gd_iso8859_1.data, gd_iso8859_1.length, + (void *)&gd_output.data, &gd_output.length), + "conversion from (dos charset) ISO8859-1 to (dos charset) ISO8859-1"); + torture_assert_data_blob_equal(tctx, gd_output, gd_iso8859_1, "conversion from UTF16LE to (dos charset) ISO8859-1 incorrect"); + + torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, + CH_DOS, CH_UNIX, + gd_iso8859_1.data, gd_iso8859_1.length, + (void *)&gd_output.data, &gd_output.length), + "conversion from (dos charset) ISO8859-1 to (unix charset) CP850"); + torture_assert_data_blob_equal(tctx, gd_output, gd_cp850, "conversion from UTF16LE to (unix charset) CP850 incorrect"); + + torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, + CH_DOS, CH_DISPLAY, + gd_iso8859_1.data, gd_iso8859_1.length, + (void *)&gd_output.data, &gd_output.length), + "conversion from (dos charset) ISO8859-1 to (display charset) UTF8"); + torture_assert_data_blob_equal(tctx, gd_output, gd_utf8, "conversion from UTF16LE to (display charset) UTF8 incorrect"); + + torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, + CH_DOS, CH_UTF16LE, + gd_iso8859_1.data, gd_iso8859_1.length, + (void *)&gd_output.data, &gd_output.length), + "conversion from (dos charset) ISO8859-1 to UTF16LE"); + torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le, "conversion from (dos charset) ISO8859-1 to UTF16LE"); + return true; +} + +static bool test_plato_english_iso8859_cp850(struct torture_context *tctx) +{ + struct smb_iconv_handle *iconv_handle; + DATA_BLOB plato_english_utf8 = data_blob_string_const(plato_english_ascii); + DATA_BLOB plato_english_cp850 = plato_english_utf8; + DATA_BLOB plato_english_iso8859_1 = plato_english_utf8; + DATA_BLOB plato_english_utf16le = base64_decode_data_blob(plato_english_utf16le_base64); + DATA_BLOB plato_english_output; + DATA_BLOB plato_english_output2; + + talloc_steal(tctx, plato_english_utf16le.data); + + iconv_handle = get_iconv_testing_handle(tctx, "ISO8859-1", "CP850", "UTF8"); + torture_assert(tctx, iconv_handle, "getting iconv handle"); + + torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, + CH_UTF8, CH_DOS, + plato_english_utf8.data, plato_english_utf8.length, + (void *)&plato_english_output.data, &plato_english_output.length), + "conversion from UTF8 to (dos charset) ISO8859-1"); + torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_iso8859_1, "conversion from UTF8 to (dos charset) ISO8859-1 incorrect"); + + torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, + CH_UTF8, CH_UNIX, + plato_english_utf8.data, plato_english_utf8.length, + (void *)&plato_english_output.data, &plato_english_output.length), + "conversion from UTF8 to (unix charset) CP850"); + torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_cp850, "conversion from UTF8 to (unix charset) CP850 incorrect"); + + torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, + CH_UTF8, CH_DISPLAY, + plato_english_utf8.data, plato_english_utf8.length, + (void *)&plato_english_output.data, &plato_english_output.length), + "conversion from UTF8 to (display charset) UTF8"); + torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF8 to (display charset) UTF8 incorrect"); + + torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, + CH_UTF16LE, CH_DOS, + plato_english_utf16le.data, plato_english_utf16le.length, + (void *)&plato_english_output.data, &plato_english_output.length), + "conversion from UTF16LE to (dos charset) ISO8859-1"); + torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_iso8859_1, "conversion from UTF16LE to (dos charset) ISO8859-1 incorrect"); + + torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, + CH_DOS, CH_UTF16LE, + plato_english_output.data, plato_english_output.length, + (void *)&plato_english_output2.data, &plato_english_output2.length), + "round trip conversion from (dos charset) ISO8859-1 back to UTF16LE"); + torture_assert_data_blob_equal(tctx, plato_english_output2, plato_english_utf16le, "round trip conversion from (dos charset) ISO8859-1 back to UTF16LE"); + + torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, + CH_UTF16LE, CH_UNIX, + plato_english_utf16le.data, plato_english_utf16le.length, + (void *)&plato_english_output.data, &plato_english_output.length), + "conversion from UTF16LE to (unix charset) CP850"); + torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_cp850, "conversion from UTF16LE to (unix charset) CP850 incorrect"); + + torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, + CH_UTF16LE, CH_DISPLAY, + plato_english_utf16le.data, plato_english_utf16le.length, + (void *)&plato_english_output.data, &plato_english_output.length), + "conversion from UTF16LE to (display charset) UTF8"); + torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF16LE to (display charset) UTF8 incorrect"); + + torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, + CH_DOS, CH_DOS, + plato_english_iso8859_1.data, plato_english_iso8859_1.length, + (void *)&plato_english_output.data, &plato_english_output.length), + "conversion from (dos charset) ISO8859-1 to (dos charset) ISO8859-1"); + torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_iso8859_1, "conversion from UTF16LE to (dos charset) ISO8859-1 incorrect"); + + torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, + CH_DOS, CH_UNIX, + plato_english_iso8859_1.data, plato_english_iso8859_1.length, + (void *)&plato_english_output.data, &plato_english_output.length), + "conversion from (dos charset) ISO8859-1 to (unix charset) CP850"); + torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_cp850, "conversion from UTF16LE to (unix charset) CP850 incorrect"); + + torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, + CH_DOS, CH_DISPLAY, + plato_english_iso8859_1.data, plato_english_iso8859_1.length, + (void *)&plato_english_output.data, &plato_english_output.length), + "conversion from (dos charset) ISO8859-1 to (display charset) UTF8"); + torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF16LE to (display charset) UTF8 incorrect"); + + torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, + CH_DOS, CH_UTF16LE, + plato_english_iso8859_1.data, plato_english_iso8859_1.length, + (void *)&plato_english_output.data, &plato_english_output.length), + "conversion from (dos charset) ISO8859-1 to UTF16LE"); + torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf16le, "conversion from (dos charset) ISO8859-1 to UTF16LE"); + return true; +} + +static bool test_plato_cp850_utf8(struct torture_context *tctx) +{ + struct smb_iconv_handle *iconv_handle; + DATA_BLOB plato_utf8 = base64_decode_data_blob(plato_utf8_base64); + DATA_BLOB plato_utf16le = base64_decode_data_blob(plato_utf16le_base64); + DATA_BLOB plato_output; + DATA_BLOB plato_output2; + + talloc_steal(tctx, plato_utf8.data); + talloc_steal(tctx, plato_utf16le.data); + + iconv_handle = get_iconv_testing_handle(tctx, "CP850", "UTF8", "UTF8"); + torture_assert(tctx, iconv_handle, "creating iconv handle"); + + torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, + CH_UTF8, CH_DOS, + plato_utf8.data, plato_utf8.length, + (void *)&plato_output.data, &plato_output.length) == false, + "conversion of UTF8 ancient greek to DOS charset CP850 should fail"); + + torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, -- Samba Shared Repository