about summary refs log tree commit diff
path: root/iconvdata
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@gmail.com>2011-05-14 11:37:36 -0400
committerUlrich Drepper <drepper@gmail.com>2011-05-14 11:37:36 -0400
commit98d76b46d2db565b22be647d611cc2649ba6ff87 (patch)
tree3b9b043995b0b9e9a4c4c0980e5ff5781fc948cf /iconvdata
parent32ad1972a8e458a555c58ca28d272ef7009d3514 (diff)
downloadglibc-98d76b46d2db565b22be647d611cc2649ba6ff87.tar.gz
glibc-98d76b46d2db565b22be647d611cc2649ba6ff87.tar.xz
glibc-98d76b46d2db565b22be647d611cc2649ba6ff87.zip
Fix handling of conversion problem in CP932 module
Diffstat (limited to 'iconvdata')
-rw-r--r--iconvdata/Makefile2
-rw-r--r--iconvdata/bug-iconv8.c43
-rw-r--r--iconvdata/cp932.c76
3 files changed, 81 insertions, 40 deletions
diff --git a/iconvdata/Makefile b/iconvdata/Makefile
index d79756cbdd..e0fe46aa72 100644
--- a/iconvdata/Makefile
+++ b/iconvdata/Makefile
@@ -68,7 +68,7 @@ include ../Makeconfig
 
 ifeq (yes,$(build-shared))
 tests = bug-iconv1 bug-iconv2 tst-loading tst-e2big tst-iconv4 bug-iconv4 \
-	tst-iconv6 bug-iconv5 bug-iconv6 tst-iconv7
+	tst-iconv6 bug-iconv5 bug-iconv6 tst-iconv7 bug-iconv8
 ifeq ($(have-thread-library),yes)
 tests += bug-iconv3
 endif
diff --git a/iconvdata/bug-iconv8.c b/iconvdata/bug-iconv8.c
new file mode 100644
index 0000000000..54c6be2f63
--- /dev/null
+++ b/iconvdata/bug-iconv8.c
@@ -0,0 +1,43 @@
+// BZ 12601
+#include <stdio.h>
+#include <errno.h>
+#include <iconv.h>
+
+static int
+do_test (void)
+{
+   iconv_t cd;
+   char in[] = "\x83\xd9";
+   char out[256];
+   char *inbuf;
+   size_t inbytesleft;
+   char *outbuf;
+   size_t outbytesleft;
+   size_t ret;
+
+   inbuf = in;
+   inbytesleft = sizeof(in) - 1;
+   outbuf = out;
+   outbytesleft = sizeof(out);
+
+   cd = iconv_open("utf-8", "cp932");
+   ret = iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
+   iconv_close(cd);
+
+   printf("result: %ld %d %ld %d\n", ret, errno, inbytesleft, inbuf[0]);
+
+   /*
+    * result: -1 84 0 0        (84=EILSEQ)
+    *
+    * Error is returnd but inbuf is consumed.
+    *
+    * \x83\xd9 is valid shift-jis sequence but no character is assigned
+    * to it.
+    */
+
+   return (ret != -1 || errno != EILSEQ
+	   || inbytesleft != 2 || inbuf[0] != in[0]);
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/iconvdata/cp932.c b/iconvdata/cp932.c
index 90ecad96bd..00d83d4557 100644
--- a/iconvdata/cp932.c
+++ b/iconvdata/cp932.c
@@ -1,5 +1,5 @@
 /* Mapping tables for CP932 handling.
-   Copyright (C) 1997,1998,1999,2000,2001,2003 Free Software Foundation, Inc.
+   Copyright (C) 1997-2001,2003,2011 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by MORIYAMA Masayuki <msyk@mtg.biglobe.ne.jp>, 2003.
 
@@ -4549,8 +4549,8 @@ static const char from_ucs4_extra[229][2] =
       ++inptr;								      \
     else if (ch >= 0xa1 && ch <= 0xdf)                                        \
       {                                                                       \
-        ch += 0xfec0;                                                         \
-        ++inptr;                                                              \
+	ch += 0xfec0;                                                         \
+	++inptr;                                                              \
       }									      \
     else if (__builtin_expect (ch, 0) == 0xa0				      \
 	     || __builtin_expect (ch <= 0x80, 0)			      \
@@ -4588,65 +4588,63 @@ static const char from_ucs4_extra[229][2] =
 	if (__builtin_expect (ch2 < 0x40, 0)				      \
 	    || __builtin_expect (ch2 > 0xfc, 0)				      \
 	    || __builtin_expect (ch2 == 0x7f, 0)			      \
-	    || (__builtin_expect (idx > 0x84be, 0) && idx < 0x8740)      \
-	    || (__builtin_expect (idx > 0x879c, 0) && idx < 0x889f)      \
-	    || (__builtin_expect (idx > 0x88fc, 0) && idx < 0x8940)      \
-	    || (__builtin_expect (idx > 0x9ffc, 0) && idx < 0xe040)      \
-	    || (__builtin_expect (idx > 0xeaa4, 0) && idx < 0xed40)      \
-	    || (__builtin_expect (idx > 0xeefc, 0) && idx < 0xf040)      \
+	    || (__builtin_expect (idx > 0x84be, 0) && idx < 0x8740)	      \
+	    || (__builtin_expect (idx > 0x879c, 0) && idx < 0x889f)	      \
+	    || (__builtin_expect (idx > 0x88fc, 0) && idx < 0x8940)	      \
+	    || (__builtin_expect (idx > 0x9ffc, 0) && idx < 0xe040)	      \
+	    || (__builtin_expect (idx > 0xeaa4, 0) && idx < 0xed40)	      \
+	    || (__builtin_expect (idx > 0xeefc, 0) && idx < 0xf040)	      \
 	    || __builtin_expect (idx > 0xfc4b, 0))			      \
 	  {								      \
 	    /* This is illegal.  */					      \
 	    if (! ignore_errors_p ())					      \
 	      {								      \
-	        /* This is an illegal character.  */			      \
-	        result = __GCONV_ILLEGAL_INPUT;				      \
-	        break;							      \
+		/* This is an illegal character.  */			      \
+		result = __GCONV_ILLEGAL_INPUT;				      \
+		break;							      \
 	      }								      \
 									      \
 	    ++inptr;							      \
 	    ++*irreversible;						      \
 	    continue;							      \
 	  }								      \
-	else								      \
-	  {								      \
-	    /* We could pack the data a bit more dense.  The second	      \
-	       byte will never be 0x7f and it will also be never	      \
-	       >0xfc.  But this would mean yet more `if's.  */		      \
-	    if (idx <= 0x84be)						      \
-	      ch = cjk_block1[(ch - 0x81) * 192 + ch2 - 0x40];		      \
-	    else if (idx <= 0x879c)					      \
-	      ch = cjk_block2[(ch - 0x87) * 192 + ch2 - 0x40];		      \
-	    else if (idx <= 0x88fc)					      \
-	      ch = cjk_block3[(ch - 0x88) * 192 + ch2 - 0x9f];		      \
-	    else if (idx <= 0x9ffc)					      \
-	      ch = cjk_block4[(ch - 0x89) * 192 + ch2 - 0x40];		      \
-	    else if (idx <= 0xeaa4)					      \
-	      ch = cjk_block5[(ch - 0xe0) * 192 + ch2 - 0x40];		      \
-	    else if (idx <= 0xeefc)					      \
-	      ch = cjk_block6[(ch - 0xed) * 192 + ch2 - 0x40];		      \
-	    else if (idx <= 0xf9fc)					      \
-	      ch = (ch-0xf0)*188 + ch2-((ch2<0x7f)?0x40:0x41) + 0xe000;	      \
-	    else							      \
-	      ch = cjk_block7[(ch - 0xfa) * 192 + ch2 - 0x40];		      \
 									      \
-	    inptr += 2;							      \
-	  }								      \
+	/* We could pack the data a bit more dense.  The second		      \
+	   byte will never be 0x7f and it will also be never		      \
+	   >0xfc.  But this would mean yet more `if's.  */		      \
+	if (idx <= 0x84be)						      \
+	  ch = cjk_block1[(ch - 0x81) * 192 + ch2 - 0x40];		      \
+	else if (idx <= 0x879c)						      \
+	  ch = cjk_block2[(ch - 0x87) * 192 + ch2 - 0x40];		      \
+	else if (idx <= 0x88fc)						      \
+	  ch = cjk_block3[(ch - 0x88) * 192 + ch2 - 0x9f];		      \
+	else if (idx <= 0x9ffc)						      \
+	  ch = cjk_block4[(ch - 0x89) * 192 + ch2 - 0x40];		      \
+	else if (idx <= 0xeaa4)						      \
+	  ch = cjk_block5[(ch - 0xe0) * 192 + ch2 - 0x40];		      \
+	else if (idx <= 0xeefc)						      \
+	  ch = cjk_block6[(ch - 0xed) * 192 + ch2 - 0x40];		      \
+	else if (idx <= 0xf9fc)						      \
+	  ch = (ch-0xf0)*188 + ch2-((ch2<0x7f)?0x40:0x41) + 0xe000;	      \
+	else								      \
+	  ch = cjk_block7[(ch - 0xfa) * 192 + ch2 - 0x40];		      \
 									      \
 	if (__builtin_expect (ch, 1) == 0)				      \
 	  {								      \
 	    /* This is an illegal character.  */			      \
 	    if (! ignore_errors_p ())					      \
 	      {								      \
-	        /* This is an illegal character.  */			      \
-	        result = __GCONV_ILLEGAL_INPUT;				      \
-	        break;							      \
+		/* This is an illegal character.  */			      \
+		result = __GCONV_ILLEGAL_INPUT;				      \
+		break;							      \
 	      }								      \
 									      \
 	    inptr += 2;							      \
 	    ++*irreversible;						      \
 	    continue;							      \
 	  }								      \
+									      \
+	inptr += 2;							      \
       }									      \
 									      \
     put32 (outptr, ch);							      \
@@ -4674,7 +4672,7 @@ static const char from_ucs4_extra[229][2] =
 	else if (ch >= 0x2010 && ch <= 0x9fa0)				      \
 	  cp = from_ucs4_cjk[ch - 0x2010];				      \
 	else if (ch >= 0xe000 && ch <= 0xe757)				      \
-          {								      \
+	  {								      \
 	    pua[0] = (ch - 0xe000) / 188 + 0xf0;			      \
 	    pua[1] = (ch - 0xe000) % 188 + 0x40;			      \
 	    if (pua[1] > 0x7e)						      \