]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Fix handling of conversion problem in CP932 module
authorUlrich Drepper <drepper@gmail.com>
Sat, 14 May 2011 15:37:36 +0000 (11:37 -0400)
committerUlrich Drepper <drepper@gmail.com>
Sat, 14 May 2011 15:37:36 +0000 (11:37 -0400)
ChangeLog
NEWS
iconvdata/Makefile
iconvdata/bug-iconv8.c [new file with mode: 0644]
iconvdata/cp932.c

index 70a4b86866ea7ba9ae4e489f8af5b2fba08494d7..549a23dcdb8b6ba2717e7eb5ec2d87c5ca0a8747 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2011-05-14  Ulrich Drepper  <drepper@gmail.com>
 
+       [BZ #12601]
+       * iconvdata/cp932.c (BODY to UCS4): Fix incrementing inptr in case of
+       two-byte sequence errors.
+       * iconvdata/Makefile (tests): Add bug-iconv8.
+       * iconvdata/bug-iconv8.c: New file.
+
        [BZ #12626]
        * sysdeps/generic/elf/backtracesymsfd.c (__backtrace_symbols_fd): Move
        buf2 definition.
diff --git a/NEWS b/NEWS
index 4abf3f04173c85c8371eaa5b2eb3a2c5f3193e0f..3db9aea549beebaaf6612035a140a4b16ce8af0c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -12,9 +12,9 @@ Version 2.14
   386, 11257, 11258, 11487, 11532, 11578, 11653, 11668, 11724, 11945, 11947,
   12052, 12158, 12178, 12200, 12346, 12393, 12420, 12432, 12445, 12449,
   12454, 12460, 12469, 12489, 12509, 12510, 12511, 12518, 12527, 12541,
-  12545, 12551, 12583, 12587, 12597, 12611, 12625, 12626, 12631, 12650,
-  12653, 12655, 12660, 12681, 12685, 12711, 12713, 12714, 12717, 12723,
-  12724, 12734, 12738
+  12545, 12551, 12583, 12587, 12597, 12601, 12611, 12625, 12626, 12631,
+  12650, 12653, 12655, 12660, 12681, 12685, 12711, 12713, 12714, 12717,
+  12723, 12724, 12734, 12738
 
 * The RPC implementation in libc is obsoleted.  Old programs keep working
   but new programs cannot be linked with the routines in libc anymore.
index d79756cbdd1765e70186c75c4ec581746c5574ad..e0fe46aa720b74c4aae23e5c5fa7080a6f74344f 100644 (file)
@@ -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 (file)
index 0000000..54c6be2
--- /dev/null
@@ -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"
index 90ecad96bd8a92b328419bb1e43e605539299513..00d83d455765bb6e533d5bf7e3a561b30ffd233a 100644 (file)
@@ -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)                                                \