changeset 10407:2575b6d4b6b5

Check behaviour when converting from UTF-7.
author Bruno Haible <bruno@clisp.org>
date Sun, 07 Sep 2008 23:20:21 +0200
parents 5991da96e696
children b59f0c45c546
files ChangeLog tests/test-striconveh.c
diffstat 2 files changed, 77 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 2008-09-07  Bruno Haible  <bruno@clisp.org>
 
+	* tests/test-striconveh.c (main): Check behaviour when converting from
+	UTF-7.
+
 	Make striconveh work better with stateful encodings.
 	* lib/striconveh.c (iconv_carefully, iconv_carefully_1): Don't assume
 	that iconv does not increment the inptr when returning -1/EINVAL.
--- a/tests/test-striconveh.c
+++ b/tests/test-striconveh.c
@@ -71,6 +71,7 @@
   iconv_t cd_utf8_to_88591 = iconv_open ("ISO-8859-1", "UTF-8");
   iconv_t cd_88592_to_utf8 = iconv_open ("UTF-8", "ISO-8859-2");
   iconv_t cd_utf8_to_88592 = iconv_open ("ISO-8859-2", "UTF-8");
+  iconv_t cd_utf7_to_utf8 = iconv_open ("UTF-8", "UTF-7");
 
   ASSERT (cd_88591_to_utf8 != (iconv_t)(-1));
   ASSERT (cd_utf8_to_88591 != (iconv_t)(-1));
@@ -335,6 +336,79 @@
 	}
     }
 
+  if (cd_utf7_to_utf8 != (iconv_t)(-1))
+    {
+      /* Disabled on Solaris, because Solaris 9 iconv() is buggy: it returns
+	 -1 / EILSEQ when converting the 7th byte of the input "+VDLYP9hA".  */
+# if !(defined __sun && !defined _LIBICONV_VERSION)
+      /* Test conversion from UTF-7 to UTF-8 with EINVAL.  */
+      for (h = 0; h < SIZEOF (handlers); h++)
+	{
+	  enum iconv_ilseq_handler handler = handlers[h];
+	  /* This is base64 encoded 0x54 0x32 0xD8 0x3F 0xD8 0x40.  It would
+	     convert to U+5432 U+D83F U+D840 but these are Unicode surrogates.  */
+	  static const char input[] = "+VDLYP9hA";
+	  static const char expected1[] = "\345\220\262"; /* 吲 glibc */
+	  static const char expected2[] = ""; /* libiconv */
+	  char *result = NULL;
+	  size_t length = 0;
+	  int retval = mem_cd_iconveh (input, 7,
+				       cd_utf7_to_utf8,
+				       cd_utf7_to_utf8, (iconv_t)(-1),
+				       handler,
+				       NULL,
+				       &result, &length);
+	  ASSERT (retval == 0);
+	  ASSERT (length == strlen (expected1) || length == strlen (expected2));
+	  ASSERT (result != NULL);
+	  if (length == strlen (expected1))
+	    ASSERT (memcmp (result, expected1, strlen (expected1)) == 0);
+	  else
+	    ASSERT (memcmp (result, expected2, strlen (expected2)) == 0);
+	  free (result);
+	}
+
+      /* Test conversion from UTF-7 to UTF-8 with EILSEQ.  */
+      for (h = 0; h < SIZEOF (handlers); h++)
+	{
+	  enum iconv_ilseq_handler handler = handlers[h];
+	  /* This is base64 encoded 0xD8 0x3F 0xD8 0x40 0xD8 0x41.  It would
+	     convert to U+D83F U+D840 U+D841 but these are Unicode surrogates.  */
+	  static const char input[] = "+2D/YQNhB";
+	  char *result = NULL;
+	  size_t length = 0;
+	  int retval = mem_cd_iconveh (input, strlen (input),
+				       cd_utf7_to_utf8,
+				       cd_utf7_to_utf8, (iconv_t)(-1),
+				       handler,
+				       NULL,
+				       &result, &length);
+	  switch (handler)
+	    {
+	    case iconveh_error:
+	      ASSERT (retval == -1 && errno == EILSEQ);
+	      ASSERT (result == NULL);
+	      break;
+	    case iconveh_question_mark:
+	    case iconveh_escape_sequence:
+	      {
+		static const char expected1[] = "?????"; /* glibc */
+		static const char expected2[] = "?2D/YQNhB"; /* libiconv */
+		ASSERT (retval == 0);
+		ASSERT (length == strlen (expected1) || length == strlen (expected2));
+		ASSERT (result != NULL);
+		if (length == strlen (expected1))
+		  ASSERT (memcmp (result, expected1, strlen (expected1)) == 0);
+		else
+		  ASSERT (memcmp (result, expected2, strlen (expected2)) == 0);
+		free (result);
+	      }
+	      break;
+	    }
+	}
+# endif
+    }
+
   /* ------------------------ Test str_cd_iconveh() ------------------------ */
 
   /* Test conversion from ISO-8859-2 to ISO-8859-1 with no errors.  */