Fix an endless loop in the conversion to wchar_t.
diff --git a/ChangeLog b/ChangeLog
index bf6ed29..69a2eb5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2009-07-07 Bruno Haible <bruno@clisp.org>
+
+ Fix an endless loop.
+ * lib/loop_wchar.h (wchar_to_loop_convert): Handle the case of
+ incomplete input correctly.
+ * tests/test-to-wchar.c: New file.
+ * tests/Makefile.in (tests-to-wchar, tests-to-wchar.o): New rules.
+ (check): Depend on and run tests-to-wchar.
+ (clean): Add tests-to-wchar.
+ Reported by Tristan Gingold <gingold@adacore.com>.
+
2009-06-30 Bruno Haible <bruno@clisp.org>
* Version 1.13.1 released.
diff --git a/NEWS b/NEWS
index fdced15..57ef5c9 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,5 @@
+* Fixed a bug in the conversion to wchar_t.
+
New in 1.13:
* The library and the iconv program now understand platform dependent aliases,
for better compatibility with the platform's own iconv_open function.
diff --git a/lib/loop_wchar.h b/lib/loop_wchar.h
index 30d5dbd..e8dc68c 100644
--- a/lib/loop_wchar.h
+++ b/lib/loop_wchar.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2002, 2005-2006, 2008 Free Software Foundation, Inc.
+ * Copyright (C) 2000-2002, 2005-2006, 2008-2009 Free Software Foundation, Inc.
* This file is part of the GNU LIBICONV Library.
*
* The GNU LIBICONV Library is free software; you can redistribute it
@@ -321,7 +321,8 @@
size_t result = 0;
while (*inbytesleft > 0) {
size_t incount;
- for (incount = 1; incount <= *inbytesleft; incount++) {
+ for (incount = 1; ; ) {
+ /* Here incount <= *inbytesleft. */
char buf[BUF_SIZE];
const char* inptr = *inbuf;
size_t inleft = incount;
@@ -403,6 +404,12 @@
break;
}
}
+ incount++;
+ if (incount > *inbytesleft) {
+ /* Incomplete input. */
+ errno = EINVAL;
+ return -1;
+ }
}
}
return result;
diff --git a/tests/Makefile.in b/tests/Makefile.in
index 86117a0..5e29be3 100644
--- a/tests/Makefile.in
+++ b/tests/Makefile.in
@@ -28,7 +28,7 @@
all :
-check : all table-from table-to ../src/iconv_no_i18n test-shiftseq
+check : all table-from table-to ../src/iconv_no_i18n test-shiftseq test-to-wchar
$(srcdir)/check-stateless $(srcdir) ASCII
# /* General multi-byte encodings */
$(CC) $(LDFLAGS) $(INCLUDES) $(CFLAGS) $(CPPFLAGS) $(srcdir)/genutf8.c ../srclib/libicrt.a -o genutf8 && \
@@ -157,6 +157,8 @@
$(srcdir)/check-subst
# /* shift sequence before invalid multibyte character */
./test-shiftseq
+# /* conversion to wchar_t */
+ ./test-to-wchar
check-extra: check-extra-@USE_EXTRA_ENCODINGS@
check-extra-no:
@@ -217,6 +219,12 @@
test-shiftseq.@OBJEXT@ : $(srcdir)/test-shiftseq.c
$(CC) -c $(INCLUDES) $(CFLAGS) $(CPPFLAGS) $(srcdir)/test-shiftseq.c
+test-to-wchar : test-to-wchar.@OBJEXT@ ../lib/libiconv.la
+ $(LIBTOOL_LINK) $(CC) $(LDFLAGS) $(CFLAGS) test-to-wchar.@OBJEXT@ ../srclib/libicrt.a ../lib/libiconv.la -o $@
+
+test-to-wchar.@OBJEXT@ : $(srcdir)/test-to-wchar.c
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(CPPFLAGS) $(srcdir)/test-to-wchar.c
+
# The following rule is necessary to avoid a toplevel "make -n check" failure.
../lib/libiconv.la :
cd ../lib && $(MAKE) libiconv.la
@@ -224,7 +232,7 @@
mostlyclean : clean
clean : force
- $(RM) *.@OBJEXT@ *.lo table-from table-from@EXEEXT@ table-to table-to@EXEEXT@ test-shiftseq test-shiftseq@EXEEXT@ tmp-* genutf8 genutf8@EXEEXT@ UTF-8.TXT gengb18030z gengb18030z@EXEEXT@ GB18030.TXT core *.stackdump
+ $(RM) *.@OBJEXT@ *.lo table-from table-from@EXEEXT@ table-to table-to@EXEEXT@ test-shiftseq test-shiftseq@EXEEXT@ test-to-wchar test-to-wchar@EXEEXT@ tmp-* genutf8 genutf8@EXEEXT@ UTF-8.TXT gengb18030z gengb18030z@EXEEXT@ GB18030.TXT core *.stackdump
$(RM) -r .libs _libs
distclean : clean
diff --git a/tests/test-to-wchar.c b/tests/test-to-wchar.c
new file mode 100644
index 0000000..457de66
--- /dev/null
+++ b/tests/test-to-wchar.c
@@ -0,0 +1,47 @@
+/* Copyright (C) 2009 Free Software Foundation, Inc.
+ This file is part of the GNU LIBICONV Library.
+
+ The GNU LIBICONV Library is free software; you can redistribute it
+ and/or modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ The GNU LIBICONV Library is distributed in the hope that it will be
+ useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU LIBICONV Library; see the file COPYING.LIB.
+ If not, write to the Free Software Foundation, Inc., 51 Franklin Street,
+ Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <iconv.h>
+#include <errno.h>
+
+/* This test checks that the conversion to wchar_t stops correctly when
+ the input is incomplete. Based on a bug report from
+ Tristan Gingold <gingold@adacore.com>. */
+
+int main ()
+{
+ iconv_t cd = iconv_open ("wchar_t", "UTF-8");
+ char inbuf[2] = { 0xc2, 0xa0 };
+ wchar_t outbuf[10];
+
+ char *inptr = inbuf;
+ size_t inbytesleft = 1;
+ char *outptr = (char *) outbuf;
+ size_t outbytesleft = sizeof (outbuf);
+ size_t r = iconv (cd,
+ (ICONV_CONST char **) &inptr, &inbytesleft,
+ &outptr, &outbytesleft);
+
+ if (!(r == (size_t)(-1) && errno == EINVAL))
+ abort ();
+
+ return 0;
+}