From patchwork Thu Feb 25 08:58:18 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Liebler X-Patchwork-Id: 11075 Received: (qmail 84033 invoked by alias); 25 Feb 2016 08:58:35 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 83978 invoked by uid 89); 25 Feb 2016 08:58:35 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.1 required=5.0 tests=AWL, BAYES_00, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.2 spammy=0x80000000 X-HELO: plane.gmane.org To: libc-alpha@sourceware.org From: Stefan Liebler Subject: Re: [PATCH 13/14] Fix ucs4le_internal_loop in error case. Date: Thu, 25 Feb 2016 09:58:18 +0100 Lines: 189 Message-ID: References: <1456219278-5258-1-git-send-email-stli@linux.vnet.ibm.com> <1456219278-5258-14-git-send-email-stli@linux.vnet.ibm.com> Mime-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.5.0 In-Reply-To: On 02/23/2016 06:41 PM, Joseph Myers wrote: > If this is user-visible in a release, there should be a bug filed in > Bugzilla (if there isn't one already open), and a testcase added to the > testsuite. > okay. I've filed the bug "Bug 19726 - Converting UCS4LE to INTERNAL with iconv() does not update pointers and lengths in error-case." (https://sourceware.org/bugzilla/show_bug.cgi?id=19726) This patch also adds a new testcase for this issue. The new test was tested on a s390, power, intel machine. ChangeLog: [BZ #19726] * iconv/gconv_simple.c (ucs4le_internal_loop): Update inptrp and outptrp in case of an illegal input. * iconv/tst-iconv6.c: New file. * iconv/Makefile (tests): Add tst-iconv6. diff --git a/iconv/Makefile b/iconv/Makefile index b008707..c2299c9 100644 --- a/iconv/Makefile +++ b/iconv/Makefile @@ -42,7 +42,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-iconv4 tst-iconv5 +tests = tst-iconv1 tst-iconv2 tst-iconv3 tst-iconv4 tst-iconv5 tst-iconv6 others = iconv_prog iconvconfig install-others-programs = $(inst_bindir)/iconv diff --git a/iconv/gconv_simple.c b/iconv/gconv_simple.c index 5412bd6..f66bf34 100644 --- a/iconv/gconv_simple.c +++ b/iconv/gconv_simple.c @@ -638,6 +638,8 @@ ucs4le_internal_loop (struct __gconv_step *step, continue; } + *inptrp = inptr; + *outptrp = outptr; return __GCONV_ILLEGAL_INPUT; } diff --git a/iconv/tst-iconv6.c b/iconv/tst-iconv6.c new file mode 100644 index 0000000..57d7f38 --- /dev/null +++ b/iconv/tst-iconv6.c @@ -0,0 +1,117 @@ +/* Testing ucs4le_internal_loop() in gconv_simple.c. + Copyright (C) 2016 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 + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include +#include +#include + +static int +do_test (void) +{ + iconv_t cd; + char *inptr; + size_t inlen; + char *outptr; + size_t outlen; + size_t n; + int e; + int result = 0; + +#if __BYTE_ORDER == __BIG_ENDIAN + /* On big-endian machines, ucs4le_internal_loop() swaps the bytes before + error checking. Thus the input values has to be swapped. */ +# define VALUE(val) bswap_32 (val) +#else +# define VALUE(val) val +#endif + uint32_t inbuf[3] = { VALUE (0x41), VALUE (0x80000000), VALUE (0x42) }; + uint32_t outbuf[3] = { 0, 0, 0 }; + + cd = iconv_open ("WCHAR_T", "UCS-4LE"); + if (cd == (iconv_t) -1) + { + printf ("cannot convert from UCS4LE to wchar_t: %m\n"); + return 1; + } + + inptr = (char *) inbuf; + inlen = sizeof (inbuf); + outptr = (char *) outbuf; + outlen = sizeof (outbuf); + + n = iconv (cd, &inptr, &inlen, &outptr, &outlen); + e = errno; + + if (n != (size_t) -1) + { + printf ("incorrect iconv() return value: %zd, expected -1\n", n); + result = 1; + } + + if (e != EILSEQ) + { + printf ("incorrect error value: %s, expected %s\n", + strerror (e), strerror (EILSEQ)); + result = 1; + } + + if (inptr != (char *) &inbuf[1]) + { + printf ("inptr=0x%p does not point to invalid character! Expected=0x%p\n" + , inptr, &inbuf[1]); + result = 1; + } + + if (inlen != sizeof (inbuf) - sizeof (uint32_t)) + { + printf ("inlen=%zd != %zd\n" + , inlen, sizeof (inbuf) - sizeof (uint32_t)); + result = 1; + } + + if (outptr != (char *) &outbuf[1]) + { + printf ("outptr=0x%p does not point to invalid character in inbuf! " + "Expected=0x%p\n" + , outptr, &outbuf[1]); + result = 1; + } + + if (outlen != sizeof (inbuf) - sizeof (uint32_t)) + { + printf ("outlen=%zd != %zd\n" + , outlen, sizeof (outbuf) - sizeof (uint32_t)); + result = 1; + } + + if (outbuf[0] != 0x41 || outbuf[1] != 0 || outbuf[2] != 0) + { + puts ("Characters conversion is incorrect!"); + result = 1; + } + + iconv_close (cd); + + return result; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" -- 2.3.0