diff options
author | Ulrich Drepper <drepper@gmail.com> | 2011-05-14 11:37:36 -0400 |
---|---|---|
committer | Ulrich Drepper <drepper@gmail.com> | 2011-05-14 11:37:36 -0400 |
commit | 98d76b46d2db565b22be647d611cc2649ba6ff87 (patch) | |
tree | 3b9b043995b0b9e9a4c4c0980e5ff5781fc948cf /iconvdata | |
parent | 32ad1972a8e458a555c58ca28d272ef7009d3514 (diff) | |
download | glibc-98d76b46d2db565b22be647d611cc2649ba6ff87.zip glibc-98d76b46d2db565b22be647d611cc2649ba6ff87.tar.gz glibc-98d76b46d2db565b22be647d611cc2649ba6ff87.tar.bz2 |
Fix handling of conversion problem in CP932 module
Diffstat (limited to 'iconvdata')
-rw-r--r-- | iconvdata/Makefile | 2 | ||||
-rw-r--r-- | iconvdata/bug-iconv8.c | 43 | ||||
-rw-r--r-- | iconvdata/cp932.c | 76 |
3 files changed, 81 insertions, 40 deletions
diff --git a/iconvdata/Makefile b/iconvdata/Makefile index d79756c..e0fe46a 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 0000000..54c6be2 --- /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 90ecad9..00d83d4 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) \ |