Bug#458579: Some ISO-2022-JP conversions cause iconv to enter an endless loop
Attached is a patch against debian sources (2.7-5), based on upstream
CVS's fix.
diff -u glibc-2.7/debian/patches/series glibc-2.7/debian/patches/series
--- glibc-2.7/debian/patches/series
+++ glibc-2.7/debian/patches/series
@@ -176,0 +177 @@
+any/cvs-iconv-iso2022jp-loop-bug.diff
only in patch2:
unchanged:
--- glibc-2.7.orig/debian/patches/any/cvs-iconv-iso2022jp-loop-bug.diff
+++ glibc-2.7/debian/patches/any/cvs-iconv-iso2022jp-loop-bug.diff
@@ -0,0 +1,85 @@
+diff -Naur glibc-2.7.old/iconv/loop.c glibc-2.7/iconv/loop.c
+--- glibc-2.7.old/iconv/loop.c 2005-09-25 16:42:36.000000000 +0000
++++ glibc-2.7/iconv/loop.c 2008-01-01 21:41:50.000000000 +0000
+@@ -225,7 +225,12 @@
+ } \
+ /* If any of them recognized the input continue with the loop. */ \
+ if (result != __GCONV_ILLEGAL_INPUT) \
+- continue; \
++ { \
++ if (__builtin_expect (result == __GCONV_FULL_OUTPUT, 0)) \
++ break; \
++ \
++ continue; \
++ } \
+ \
+ /* Next see whether we have to ignore the error. If not, stop. */ \
+ if (! ignore_errors_p ()) \
+diff -Naur glibc-2.7.old/iconvdata/bug-iconv6.c glibc-2.7/iconvdata/bug-iconv6.c
+--- glibc-2.7.old/iconvdata/bug-iconv6.c 1970-01-01 00:00:00.000000000 +0000
++++ glibc-2.7/iconvdata/bug-iconv6.c 2008-01-01 21:41:50.000000000 +0000
+@@ -0,0 +1,52 @@
++#include <string.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <errno.h>
++#include <iconv.h>
++#include <locale.h>
++
++static const char testbuf[] = {
++ 0xEF, 0xBE, 0x9F, 0xD0, 0xB4, 0xEF, 0xBE, 0x9F, 0x29, 0xEF, 0xBE, 0x8E,
++ 0xEF, 0xBE, 0x9F, 0xEF, 0xBD, 0xB6, 0xEF, 0xBD, 0xB0, 0xEF, 0xBE, 0x9D
++};
++
++static int
++do_test (void)
++{
++ setlocale (LC_ALL, "en_US.UTF-8");
++ iconv_t ic = iconv_open ("ISO-2022-JP//TRANSLIT", "UTF-8");
++ if (ic == (iconv_t) -1)
++ {
++ puts ("iconv_open failed");
++ return 1;
++ }
++ size_t outremain = sizeof testbuf;
++ char outbuf[outremain];
++ char *inp = (char *) testbuf;
++ char *outp = outbuf;
++ size_t inremain = sizeof testbuf;
++
++ int ret = iconv (ic, &inp, &inremain, &outp, &outremain);
++
++ int result = 0;
++ if (ret == (size_t) -1)
++ {
++ if (errno == E2BIG)
++ puts ("buffer too small reported. OK");
++ else
++ {
++ printf ("iconv failed with %d (%m)\n", errno);
++ result = 0;
++ }
++ }
++ else
++ {
++ printf ("iconv returned %d\n", ret);
++ result = 1;
++ }
++
++ return result;
++}
++
++#define TEST_FUNCTION do_test ()
++#include "../test-skeleton.c"
+diff -Naur glibc-2.7.old/iconvdata/Makefile glibc-2.7/iconvdata/Makefile
+--- glibc-2.7.old/iconvdata/Makefile 2007-09-30 04:00:02.000000000 +0000
++++ glibc-2.7/iconvdata/Makefile 2008-01-01 21:42:01.000000000 +0000
+@@ -67,7 +67,7 @@
+
+ ifeq (yes,$(build-shared))
+ tests = bug-iconv1 bug-iconv2 tst-loading tst-e2big tst-iconv4 bug-iconv4 \
+- tst-iconv6 bug-iconv5
++ tst-iconv6 bug-iconv5 bug-iconv6
+ ifeq ($(have-thread-library),yes)
+ tests += bug-iconv3
+ endif
Reply to: