aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--iconv/Makefile5
-rw-r--r--iconv/gconv_trans.c7
-rw-r--r--iconv/tst-iconv4.c65
4 files changed, 80 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index fcbc343a40..e79c0abb6a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2009-02-02 Ulrich Drepper <drepper@redhat.com>
+
+ [BZ #9793]
+ * iconv/gconv_trans.c (__gconv_transliterate): Don't change
+ *OUTBUFSTART unless the whole output fit into the buffer.
+ * iconv/Makefile (tests): Add tst-iconv4.
+ * iconv/tst-iconv4.c: New file.
+
2009-02-01 Ulrich Drepper <drepper@redhat.com>
* sysdeps/x86_64/cacheinfo.c (intel_02_known): Add new descriptors.
diff --git a/iconv/Makefile b/iconv/Makefile
index f0f16f81b3..77a9ad7666 100644
--- a/iconv/Makefile
+++ b/iconv/Makefile
@@ -1,5 +1,4 @@
-# Copyright (C) 1997,1998,2000,2001,2002,2003,2004,2007
-# Free Software Foundation, Inc.
+# Copyright (C) 1997,1998,2000-2004,2007,2009 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# The GNU C Library is free software; you can redistribute it and/or
@@ -50,7 +49,7 @@ CFLAGS-charmap.c = -DCHARMAP_PATH='"$(i18ndir)/charmaps"' \
CFLAGS-linereader.c = -DNO_TRANSLITERATION
CFLAGS-simple-hash.c = -I../locale
-tests = tst-iconv1 tst-iconv2 tst-iconv3 tst-iconv5
+tests = tst-iconv1 tst-iconv2 tst-iconv3 tst-iconv4 tst-iconv5
distribute = gconv_builtin.h gconv_int.h loop.c skeleton.c iconv_prog.h \
iconv_charmap.c dummy-repertoire.c gconv_charset.h strtab.c \
diff --git a/iconv/gconv_trans.c b/iconv/gconv_trans.c
index 9e04e64ee2..1f1dd01b19 100644
--- a/iconv/gconv_trans.c
+++ b/iconv/gconv_trans.c
@@ -1,5 +1,5 @@
/* Transliteration using the locale's data.
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 2000.
@@ -139,7 +139,10 @@ __gconv_transliterate (struct __gconv_step *step,
++*irreversible;
res = __GCONV_OK;
}
- *outbufstart = outptr;
+ /* Do not increment the output pointer if we could not
+ store the entire output. */
+ if (res != __GCONV_FULL_OUTPUT)
+ *outbufstart = outptr;
return res;
}
diff --git a/iconv/tst-iconv4.c b/iconv/tst-iconv4.c
new file mode 100644
index 0000000000..b5ff39306c
--- /dev/null
+++ b/iconv/tst-iconv4.c
@@ -0,0 +1,65 @@
+// Derived from BZ #9793
+#include <errno.h>
+#include <iconv.h>
+#include <stdio.h>
+
+
+static int
+do_test (void)
+{
+ iconv_t cd = iconv_open ("ASCII//TRANSLIT", "UTF-8");
+ if (cd == (iconv_t) -1)
+ {
+ puts ("iconv_open failed");
+ return 1;
+ }
+
+ char input[2] = { 0xc2, 0xae }; /* Registered trademark */
+ char *inptr = input;
+ size_t insize = sizeof (input);
+ char output[2]; /* Too short to contain "(R)". */
+ char *outptr = output;
+ size_t outsize = sizeof (output);
+
+ size_t ret = iconv (cd, &inptr, &insize, &outptr, &outsize);
+ if (ret != (size_t) -1)
+ {
+ puts ("iconv succeeded");
+ return 1;
+ }
+ if (errno != E2BIG)
+ {
+ puts ("iconv did not set errno to E2BIG");
+ return 1;
+ }
+ int res = 0;
+ if (inptr != input)
+ {
+ puts ("inptr changed");
+ res = 1;
+ }
+ if (insize != sizeof (input))
+ {
+ puts ("insize changed");
+ res = 1;
+ }
+ if (outptr != output)
+ {
+ puts ("outptr changed");
+ res = 1;
+ }
+ if (outsize != sizeof (output))
+ {
+ puts ("outsize changed");
+ res = 1;
+ }
+ if (iconv_close (cd) == -1)
+ {
+ puts ("iconv_close failed");
+ res = 1;
+ }
+ return res;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"