diff options
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | iconv/Makefile | 5 | ||||
-rw-r--r-- | iconv/gconv_trans.c | 7 | ||||
-rw-r--r-- | iconv/tst-iconv4.c | 65 |
4 files changed, 80 insertions, 5 deletions
@@ -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" |