[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Wed Apr 27 20:14:03 MDT 2011


The branch, master has been updated
       via  790ab3e lib/util/charset Add copyright headers
       via  d17f435 lib/util/charset Make fast path from UTF16 to '8 bit' charsets clearer
       via  eee1ff2 lib/util/charset Add tests for srclen=-1 behaviour.
       via  4081ea5 lib/util/charset use convert_string.c in common
       via  75d5ba4 lib/util/charset Fix string termination conditions for UTF16 strings
      from  240465f Remove another fstring in this code.

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 790ab3e0dbd77ba2d08ef9c39d00f542fbe01358
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Thu Apr 28 10:56:36 2011 +1000

    lib/util/charset Add copyright headers
    
    Autobuild-User: Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date: Thu Apr 28 04:13:44 CEST 2011 on sn-devel-104

commit d17f4352fe2493be433a21e2f47453968aafdc4d
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Apr 28 10:50:06 2011 +1000

    lib/util/charset Make fast path from UTF16 to '8 bit' charsets clearer
    
    This breaks the fast path into handling for -1 and handling for
    specified lenghts, avoding branch operations on each character.
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>
    Signed-off-by: Andrew Tridgell <tridge at samba.org>

commit eee1ff2fb56f46fb3c6aa7dfe51583e3b489fb5d
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Thu Apr 28 10:48:43 2011 +1000

    lib/util/charset Add tests for srclen=-1 behaviour.
    
    This confirms that we do include a null terminator in all non-failed
    conversions.
    
    Andrew Bartlett
    
    Signed-off-by: Andrew Tridgell <tridge at samba.org>

commit 4081ea5b49c6b882174d633a1eb03436341c4e63
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Apr 12 14:49:41 2011 +1000

    lib/util/charset use convert_string.c in common
    
    This brings another layer of the charcnv library in common.
    
    Andrew Bartlett
    
    Signed-off-by: Andrew Tridgell <tridge at samba.org>

commit 75d5ba4109801957eef590b601cce61a6e67064f
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Thu Apr 14 17:23:25 2011 +1000

    lib/util/charset Fix string termination conditions for UTF16 strings
    
    This punts partial UTF16 strings to iconv() to deal with, as it's not
    a fast path any longer if it's got an odd length.
    
    Andrew Bartlett
    
    Signed-off-by: Andrew Tridgell <tridge at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 lib/util/charset/charcnv.c              |  135 ----------
 lib/util/charset/convert_string.c       |   54 +++--
 lib/util/charset/tests/convert_string.c |  443 +++++++++++++++++++++++++++++++
 lib/util/charset/util_unistr.c          |   65 -----
 lib/util/charset/wscript_build          |    4 +-
 source3/wscript_build                   |    2 +-
 6 files changed, 481 insertions(+), 222 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/util/charset/charcnv.c b/lib/util/charset/charcnv.c
index 998bb08..076795a 100644
--- a/lib/util/charset/charcnv.c
+++ b/lib/util/charset/charcnv.c
@@ -113,138 +113,3 @@ convert:
 	return destlen;
 
 }
-
-/**
- * Convert string from one encoding to another, making error checking etc
- *
- * @param src pointer to source string (multibyte or singlebyte)
- * @param srclen length of the source string in bytes
- * @param dest pointer to destination string (multibyte or singlebyte)
- * @param destlen maximal length allowed for string
- * @returns the number of bytes occupied in the destination
- * on error, returns -1, and sets errno
- **/
-_PUBLIC_ bool convert_string_error_handle(struct smb_iconv_handle *ic,
-					  charset_t from, charset_t to,
-					  void const *src, size_t srclen,
-					  void *dest, size_t destlen,
-					  size_t *converted_size)
-{
-	size_t i_len, o_len;
-	ssize_t retval;
-	const char* inbuf = (const char*)src;
-	char* outbuf = (char*)dest;
-	smb_iconv_t descriptor;
-
-	if (srclen == (size_t)-1)
-		srclen = strlen(inbuf)+1;
-
-	descriptor = get_conv_handle(ic, from, to);
-	if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) {
-		if (converted_size) {
-			*converted_size = 0;
-		}
-		errno = EINVAL;
-		return -1;
-	}
-
-	i_len=srclen;
-	o_len=destlen;
-
-	retval = smb_iconv(descriptor,  &inbuf, &i_len, &outbuf, &o_len);
-
-	if (converted_size != NULL)
-		*converted_size = destlen-o_len;
-	return (retval != (ssize_t)-1);
-}
-
-
-/**
- * Convert string from one encoding to another, making error checking etc
- *
- * @param src pointer to source string (multibyte or singlebyte)
- * @param srclen length of the source string in bytes
- * @param dest pointer to destination string (multibyte or singlebyte)
- * @param destlen maximal length allowed for string
- * @returns the number of bytes occupied in the destination
- **/
-_PUBLIC_ bool convert_string_handle(struct smb_iconv_handle *ic,
-					 charset_t from, charset_t to,
-					 void const *src, size_t srclen,
-					 void *dest, size_t destlen, size_t *converted_size)
-{
-	bool retval;
-
-	retval = convert_string_error_handle(ic, from, to, src, srclen, dest, destlen, converted_size);
-	if(retval==false) {
-	    	const char *reason;
-		switch(errno) {
-		case EINVAL:
-			reason="Incomplete multibyte sequence";
-			return false;
-		case E2BIG:
-			reason="No more room";
-			if (from == CH_UNIX) {
-				DEBUG(0,("E2BIG: convert_string_handle(%s,%s): srclen=%d destlen=%d - '%s'\n",
-					 charset_name(ic, from), charset_name(ic, to),
-					 (int)srclen, (int)destlen,
-					 (const char *)src));
-			} else {
-				DEBUG(0,("E2BIG: convert_string_handle(%s,%s): srclen=%d destlen=%d\n",
-					 charset_name(ic, from), charset_name(ic, to),
-					 (int)srclen, (int)destlen));
-			}
-			return false;
-		case EILSEQ:
-			reason="Illegal multibyte sequence";
-			return false;
-		default:
-			return false;
-		}
-	}
-	return true;
-}
-	
-/**
- * Convert between character sets, allocating a new buffer using talloc for the result.
- *
- * @param srclen length of source buffer.
- * @param dest always set at least to NULL
- * @note -1 is not accepted for srclen.
- *
- * @returns Size in bytes of the converted string; or -1 in case of error.
- **/
-
-_PUBLIC_ bool convert_string_talloc_handle(TALLOC_CTX *ctx,
-						struct smb_iconv_handle *ic,
-						charset_t from, charset_t to, 
-						void const *src, size_t srclen, 
-						void *dst, size_t *converted_size)
-{
-	void **dest = (void **)dst;
-	smb_iconv_t descriptor;
-	ssize_t ret;
-
-	*dest = NULL;
-
-	if (src == NULL || srclen == (size_t)-1 || srclen == 0)
-		return false;
-
-	descriptor = get_conv_handle(ic, from, to);
-
-	if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) {
-		/* conversion not supported, return -1*/
-		DEBUG(3, ("convert_string_talloc_handle: conversion from %s to %s not supported!\n",
-			  charset_name(ic, from), 
-			  charset_name(ic, to)));
-		return false;
-	}
-
-	ret = iconv_talloc(ctx, descriptor, src, srclen, dest);
-	if (ret == -1)
-		return false;
-	if (converted_size != NULL)
-		*converted_size = ret;
-	return true;
-}
-
diff --git a/lib/util/charset/convert_string.c b/lib/util/charset/convert_string.c
index e51add2..51f9fec 100644
--- a/lib/util/charset/convert_string.c
+++ b/lib/util/charset/convert_string.c
@@ -2,7 +2,8 @@
    Unix SMB/CIFS implementation.
    Character set conversion Extensions
    Copyright (C) Igor Vergeichik <iverg at mail.ru> 2001
-   Copyright (C) Andrew Tridgell 2001
+   Copyright (C) Andrew Tridgell 2001-2011
+   Copyright (C) Andrew Bartlett 2011
    Copyright (C) Simo Sorce 2001
    Copyright (C) Martin Pool 2003
 
@@ -21,6 +22,7 @@
 
 */
 #include "includes.h"
+#include "system/iconv.h"
 
 /**
  * @file
@@ -177,28 +179,29 @@ bool convert_string_error_handle(struct smb_iconv_handle *ic,
 		size_t slen = srclen;
 		size_t dlen = destlen;
 		unsigned char lastp = '\0';
+		bool ret;
 
-		/* If all characters are ascii, fast path here. */
-		while (((slen == (size_t)-1) || (slen >= 2)) && dlen) {
-			if (((lastp = *p) <= 0x7f) && (p[1] == 0)) {
+		if (slen == (size_t)-1) {
+			while (dlen &&
+			       ((lastp = *p) <= 0x7f) && (p[1] == 0)) {
 				*q++ = *p;
-				if (slen != (size_t)-1) {
-					slen -= 2;
-				}
 				p += 2;
 				dlen--;
 				retval++;
 				if (!lastp)
 					break;
-			} else {
-#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
-				goto general_case;
-#else
-				bool ret = convert_string_internal(ic, from, to, p, slen, q, dlen, converted_size);
-				*converted_size += retval;
-				return ret;
-#endif
 			}
+			if (lastp != 0) goto slow_path;
+		} else {
+			while (slen >= 2 && dlen &&
+			       (*p <= 0x7f) && (p[1] == 0)) {
+				*q++ = *p;
+				slen -= 2;
+				p += 2;
+				dlen--;
+				retval++;
+			}
+			if (slen != 0) goto slow_path;
 		}
 
 		*converted_size = retval;
@@ -212,6 +215,19 @@ bool convert_string_error_handle(struct smb_iconv_handle *ic,
 			}
 		}
 		return true;
+
+	slow_path:
+		/* come here when we hit a character we can't deal
+		 * with in the fast path
+		 */
+#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
+		goto general_case;
+#else
+		ret = convert_string_internal(ic, from, to, p, slen, q, dlen, converted_size);
+		*converted_size += retval;
+		return ret;
+#endif
+
 	} else if (from != CH_UTF16LE && from != CH_UTF16BE && to == CH_UTF16LE) {
 		const unsigned char *p = (const unsigned char *)src;
 		unsigned char *q = (unsigned char *)dest;
@@ -221,8 +237,8 @@ bool convert_string_error_handle(struct smb_iconv_handle *ic,
 		unsigned char lastp = '\0';
 
 		/* If all characters are ascii, fast path here. */
-		while (slen && (dlen >= 2)) {
-			if ((lastp = *p) <= 0x7F) {
+		while (slen && (dlen >= 1)) {
+			if (dlen >=2 && (lastp = *p) <= 0x7F) {
 				*q++ = *p++;
 				*q++ = '\0';
 				if (slen != (size_t)-1) {
@@ -387,7 +403,7 @@ bool convert_string_talloc_handle(TALLOC_CTX *ctx, struct smb_iconv_handle *ic,
 	}
 
 	/* +2 is for ucs2 null termination. */
-	ob = (char *)TALLOC_REALLOC(ctx, ob, destlen + 2);
+	ob = talloc_realloc(ctx, ob, char, destlen + 2);
 
 	if (!ob) {
 		DEBUG(0, ("convert_string_talloc: realloc failed!\n"));
@@ -428,7 +444,7 @@ bool convert_string_talloc_handle(TALLOC_CTX *ctx, struct smb_iconv_handle *ic,
 	 */
 	if (o_len > 1024) {
 		/* We're shrinking here so we know the +2 is safe from wrap. */
-		ob = (char *)TALLOC_REALLOC(ctx,ob,destlen + 2);
+		ob = talloc_realloc(ctx,ob, char, destlen + 2);
 	}
 
 	if (destlen && !ob) {
diff --git a/lib/util/charset/tests/convert_string.c b/lib/util/charset/tests/convert_string.c
index 32fc11f..bd140d5 100644
--- a/lib/util/charset/tests/convert_string.c
+++ b/lib/util/charset/tests/convert_string.c
@@ -282,6 +282,191 @@ static bool test_gd_iso8859_cp850_handle(struct torture_context *tctx)
 	return true;
 }
 
+static bool test_gd_minus_1_handle(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_utf16le = base64_decode_data_blob(gd_utf16le_base64);
+	DATA_BLOB gd_output;
+	DATA_BLOB gd_utf8_terminated;
+	DATA_BLOB gd_cp850_terminated;
+	DATA_BLOB gd_utf16le_terminated;
+	
+	talloc_steal(tctx, gd_utf8.data);
+	talloc_steal(tctx, gd_cp850.data);
+	talloc_steal(tctx, gd_utf16le.data);
+
+	iconv_handle = get_iconv_testing_handle(tctx, "CP850", "CP850", "UTF8");
+	torture_assert(tctx, iconv_handle, "getting iconv handle");
+
+	gd_utf8_terminated = data_blob_talloc(tctx, NULL, gd_utf8.length + 1);
+	memcpy(gd_utf8_terminated.data, gd_utf8.data, gd_utf8.length);
+	gd_utf8_terminated.data[gd_utf8.length] = '\0';
+
+	gd_cp850_terminated = data_blob_talloc(tctx, NULL, gd_cp850.length + 1);
+	memcpy(gd_cp850_terminated.data, gd_cp850.data, gd_cp850.length);
+	gd_cp850_terminated.data[gd_cp850.length] = '\0';
+
+	gd_utf16le_terminated = data_blob_talloc(tctx, NULL, gd_utf16le.length + 2);
+	memcpy(gd_utf16le_terminated.data, gd_utf16le.data, gd_utf16le.length);
+	gd_utf16le_terminated.data[gd_utf16le.length] = '\0';
+	gd_utf16le_terminated.data[gd_utf16le.length + 1] = '\0';
+
+	gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
+
+	torture_assert(tctx, convert_string_error_handle(iconv_handle,
+							  CH_UTF8, CH_UTF16LE,
+							  gd_utf8_terminated.data, -1,
+							 (void *)gd_output.data, gd_output.length, &gd_output.length),
+		       "conversion from UTF8 to UTF16LE null terminated");
+	torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated");
+
+	gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
+	torture_assert(tctx, convert_string_error_handle(iconv_handle,
+							  CH_UTF8, CH_UTF16LE,
+							  gd_utf8_terminated.data, -1,
+							  (void *)gd_output.data, gd_utf16le.length, &gd_output.length) == false,
+		       "conversion from UTF8 to UTF16LE null terminated should fail");
+	torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
+	torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le, "conversion from UTF8 to UTF16LE null terminated");
+
+	gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
+	torture_assert(tctx, convert_string_error_handle(iconv_handle,
+							  CH_UTF8, CH_UTF16LE,
+							  gd_utf8_terminated.data, -1,
+							  (void *)gd_output.data, gd_utf16le.length - 1, &gd_output.length) == false,
+		       "conversion from UTF8 to UTF16LE null terminated should fail");
+	torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
+
+	gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
+	torture_assert(tctx, convert_string_error_handle(iconv_handle,
+							  CH_UTF8, CH_UTF16LE,
+							  gd_utf8_terminated.data, -1,
+							  (void *)gd_output.data, gd_utf16le.length - 2, &gd_output.length) == false,
+		       "conversion from UTF8 to UTF16LE null terminated should fail");
+	torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
+
+	gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10);
+	torture_assert(tctx, convert_string_error_handle(iconv_handle,
+							 CH_UTF16LE, CH_UTF8,
+							 gd_utf16le_terminated.data, -1,
+							 (void *)gd_output.data, gd_output.length, &gd_output.length),
+		       "conversion from UTF16LE to UTF8 null terminated");
+	torture_assert_data_blob_equal(tctx, gd_output, gd_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated");
+
+	gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10);
+
+	torture_assert(tctx, convert_string_error_handle(iconv_handle,
+							 CH_UTF16LE, CH_UTF8,
+							 gd_utf16le_terminated.data, -1,
+							 (void *)gd_output.data, gd_utf8.length, &gd_output.length) == false,
+		       "conversion from UTF16LE to UTF8 null terminated should fail");
+	torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
+	torture_assert_data_blob_equal(tctx, gd_output, gd_utf8, "conversion from UTF16LE to UTF8 null terminated");
+
+	gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10);
+
+	torture_assert(tctx, convert_string_error_handle(iconv_handle,
+							 CH_UTF16LE, CH_UTF8,
+							 gd_utf16le_terminated.data, -1,
+							 (void *)gd_output.data, gd_utf8.length - 1, &gd_output.length) == false,
+		       "conversion from UTF16LE to UTF8 null terminated should fail");
+	torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
+
+	gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10);
+
+	torture_assert(tctx, convert_string_error_handle(iconv_handle,
+							 CH_UTF16LE, CH_UTF8,
+							 gd_utf16le_terminated.data, -1,
+							 (void *)gd_output.data, gd_utf8.length - 2, &gd_output.length) == false,
+		       "conversion from UTF16LE to UTF8 null terminated should fail");
+	torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
+
+	gd_output = data_blob_talloc(tctx, NULL, gd_cp850.length + 10);
+
+	torture_assert(tctx, convert_string_error_handle(iconv_handle,
+							 CH_UTF16LE, CH_DOS,
+							 gd_utf16le_terminated.data, -1,
+							 (void *)gd_output.data, gd_output.length, &gd_output.length),
+		       "conversion from UTF16LE to CP850 (dos) null terminated");
+	torture_assert_data_blob_equal(tctx, gd_output, gd_cp850_terminated, "conversion from UTF16LE to CP850 (dos) null terminated");
+
+	/* Now null terminate the string early, the confirm we don't skip the NULL and convert any further */
+	gd_utf8_terminated.data[3] = '\0';
+	gd_utf8_terminated.length = 4; /* used for the comparison only */
+
+	gd_cp850_terminated.data[2] = '\0';
+	gd_cp850_terminated.length = 3; /* used for the comparison only */
+
+	gd_utf16le_terminated.data[4] = '\0';
+	gd_utf16le_terminated.data[5] = '\0';
+	gd_utf16le_terminated.length = 6; /* used for the comparison only */
+
+	gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
+
+	torture_assert(tctx, convert_string_error_handle(iconv_handle,
+							  CH_UTF8, CH_UTF16LE,
+							  gd_utf8_terminated.data, -1,
+							  (void *)gd_output.data, gd_output.length, &gd_output.length),
+		       "conversion from UTF8 to UTF16LE null terminated");
+	torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated early");
+
+	gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10);
+
+	torture_assert(tctx, convert_string_error_handle(iconv_handle,
+							  CH_UTF16LE, CH_UTF8,
+							  gd_utf16le_terminated.data, -1,
+							 (void *)gd_output.data, gd_output.length, &gd_output.length),
+		       "conversion from UTF16LE to UTF8 null terminated");
+	torture_assert_data_blob_equal(tctx, gd_output, gd_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated early");
+
+	gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
+
+	torture_assert(tctx, convert_string_error_handle(iconv_handle,
+							  CH_DOS, CH_UTF16LE,
+							  gd_cp850_terminated.data, -1,
+							  (void *)gd_output.data, gd_output.length, &gd_output.length),
+		       "conversion from CP850 to UTF16LE null terminated");
+	torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated early");
+
+	gd_output = data_blob_talloc(tctx, NULL, gd_cp850.length + 10);
+
+	torture_assert(tctx, convert_string_error_handle(iconv_handle,
+							  CH_UTF16LE, CH_DOS,
+							  gd_utf16le_terminated.data, -1,
+							 (void *)gd_output.data, gd_output.length, &gd_output.length),
+		       "conversion from UTF16LE to UTF8 null terminated");
+	torture_assert_data_blob_equal(tctx, gd_output, gd_cp850_terminated, "conversion from UTF16LE to UTF8 null terminated early");
+	
+	/* Now null terminate the string particularly early, the confirm we don't skip the NULL and convert any further */
+	gd_utf8_terminated.data[1] = '\0';
+	gd_utf8_terminated.length = 2; /* used for the comparison only */
+	
+	gd_utf16le_terminated.data[2] = '\0';
+	gd_utf16le_terminated.data[3] = '\0';
+	gd_utf16le_terminated.length = 4; /* used for the comparison only */
+
+	gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
+
+	torture_assert(tctx, convert_string_error_handle(iconv_handle, CH_UTF8, CH_UTF16LE,
+							  gd_utf8_terminated.data, -1,
+							 (void *)gd_output.data, gd_output.length, &gd_output.length),
+		       "conversion from UTF8 to UTF16LE null terminated");
+	torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated very early");
+
+	gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10);
+
+	torture_assert(tctx, convert_string_error_handle(iconv_handle,
+							  CH_UTF16LE, CH_UTF8,
+							  gd_utf16le_terminated.data, -1,
+							 (void *)gd_output.data, gd_output.length, &gd_output.length),
+		       "conversion from UTF16LE to UTF8 null terminated");
+	torture_assert_data_blob_equal(tctx, gd_output, gd_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated very early");
+
+	return true;
+}
+
 static bool test_gd_ascii_handle(struct torture_context *tctx)
 {
 	struct smb_iconv_handle *iconv_handle;
@@ -472,6 +657,261 @@ static bool test_plato_english_iso8859_cp850_handle(struct torture_context *tctx
 	return true;
 }
 
+static bool test_plato_english_minus_1_handle(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_utf16le = base64_decode_data_blob(plato_english_utf16le_base64);
+	DATA_BLOB plato_english_output;
+	DATA_BLOB plato_english_utf8_terminated;
+	DATA_BLOB plato_english_utf16le_terminated;
+	
+	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");
+
+	plato_english_utf8_terminated = data_blob_talloc(tctx, NULL, plato_english_utf8.length + 1);
+	memcpy(plato_english_utf8_terminated.data, plato_english_utf8.data, plato_english_utf8.length);
+	plato_english_utf8_terminated.data[plato_english_utf8.length] = '\0';
+
+	plato_english_utf16le_terminated = data_blob_talloc(tctx, NULL, plato_english_utf16le.length + 2);
+	memcpy(plato_english_utf16le_terminated.data, plato_english_utf16le.data, plato_english_utf16le.length);
+	plato_english_utf16le_terminated.data[plato_english_utf16le.length] = '\0';
+	plato_english_utf16le_terminated.data[plato_english_utf16le.length + 1] = '\0';
+		
+	plato_english_output = data_blob_talloc(tctx, NULL, plato_english_utf16le.length + 10);
+
+	torture_assert(tctx, convert_string_error_handle(iconv_handle,
+							  CH_UTF8, CH_UTF16LE,
+							  plato_english_utf8_terminated.data, -1,
+							 (void *)plato_english_output.data, plato_english_output.length, &plato_english_output.length),
+		       "conversion from UTF8 to UTF16LE null terminated");
+	torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated");
+
+	torture_assert(tctx, convert_string_error_handle(iconv_handle,
+							  CH_UTF8, CH_UTF16LE,
+							  plato_english_utf8_terminated.data, -1,
+							  (void *)plato_english_output.data, plato_english_utf16le.length, &plato_english_output.length) == false,
+		       "conversion from UTF8 to UTF16LE null terminated should fail");
+	torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
+	torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf16le, "conversion from UTF8 to UTF16LE null terminated");
+
+	torture_assert(tctx, convert_string_error_handle(iconv_handle,
+							  CH_UTF8, CH_UTF16LE,


-- 
Samba Shared Repository


More information about the samba-cvs mailing list