From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27054 invoked by alias); 8 Jan 2008 14:00:07 -0000 Received: (qmail 27024 invoked by uid 22791); 8 Jan 2008 14:00:05 -0000 X-Spam-Check-By: sourceware.org Received: from sunsite.ms.mff.cuni.cz (HELO sunsite.mff.cuni.cz) (195.113.15.26) by sourceware.org (qpsmtpd/0.31) with ESMTP; Tue, 08 Jan 2008 13:59:35 +0000 Received: from sunsite.mff.cuni.cz (localhost.localdomain [127.0.0.1]) by sunsite.mff.cuni.cz (8.13.8/8.13.8) with ESMTP id m08E6lOm025344; Tue, 8 Jan 2008 15:06:47 +0100 Received: (from jj@localhost) by sunsite.mff.cuni.cz (8.13.8/8.13.8/Submit) id m08E6kQi025343; Tue, 8 Jan 2008 15:06:46 +0100 Date: Tue, 08 Jan 2008 14:00:00 -0000 From: Jakub Jelinek To: Ulrich Drepper Cc: Glibc hackers Subject: [PATCH] Fix some problems with iso-2022-jp//translit conversions Message-ID: <20080108140646.GM2947@sunsite.mff.cuni.cz> Reply-To: Jakub Jelinek Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.4.2.2i Mailing-List: contact libc-hacker-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-hacker-owner@sourceware.org X-SW-Source: 2008-01/txt/msg00000.txt.bz2 Hi! See https://bugzilla.redhat.com/397021 This patch fixes two problems. One affects all conversions which use some state variables with INIT_PARAMS, UPDATE_PARAMS macros. Without this patch if STANDARD_TO_LOOP_ERR_HANDLER transliterates some character, this state isn't flushed by UPDATE_PARAMS to its standard location, so the recursive gconv invocation from within __gconv_transliterate assumes the output is in a state which it had been in when the outer gconv was called. But the characters processed within that call, before hitting the need for transliteration, could have changed state. Similarly, the transliterated string can change the state and the parent needs to reread the state back. The other bug is specific to iso-2022-jp.c - it was reusing the result variable for its purposes when trying the different character sets to see which one would match. That's fine for __GCONV_FULL_OUTPUT and for __GCONV_INVALID_INPUT it doesn't matter, since STANDARD_TO_LOOP_ERR_HANDLER sets result to that anyway. But if a set was successfully found and char converted there, it was setting result to __GCONV_OK, but the caller is expecting __GCONV_EMPTY_INPUT - __gconv_transliterate has: res = DL_CALL_FCT (fct, (step, step_data, &toinptr, (const unsigned char *) &to_tbl[idx2 + len], &outptr, NULL, 0, 0)); if (res != __GCONV_ILLEGAL_INPUT) { /* If the conversion succeeds we have to increment the input buffer. */ if (res == __GCONV_EMPTY_INPUT) { *inbufp += cnt * sizeof (uint32_t); ++*irreversible; res = __GCONV_OK; } *outbufstart = outptr; return res; } and as res was __GCONV_OK rather than the expected __GCONV_EMPTY_INPUT, *inbufp wasn't ever increased and so it looped forever. 2008-01-08 Jakub Jelinek * iconv/loop.c (UPDATE_PARAMS): Define to empty statement if not defined. (REINIT_PARAMS): Likewise. Undefine before end of file. (STANDARD_TO_LOOP_ERR_HANDLER): Use UPDATE_PARAMS before calling transliteration hooks and REINIT_PARAMS afterwards. * iconvdata/iso-2022-jp.c (BODY): Use a separate variable for status. (REINIT_PARAMS): Define. * iconvdata/ibm1364.c (REINIT_PARAMS): Likewise. * iconvdata/ibm930.c (REINIT_PARAMS): Likewise. * iconvdata/ibm933.c (REINIT_PARAMS): Likewise. * iconvdata/ibm935.c (REINIT_PARAMS): Likewise. * iconvdata/ibm937.c (REINIT_PARAMS): Likewise. * iconvdata/ibm939.c (REINIT_PARAMS): Likewise. * iconvdata/iso-2022-cn.c (REINIT_PARAMS): Likewise. * iconvdata/iso-2022-cn-ext.c (REINIT_PARAMS): Likewise. * iconvdata/iso-2022-jp-3.c (REINIT_PARAMS): Likewise. * iconvdata/iso-2022-kr.c (REINIT_PARAMS): Likewise. * iconvdata/Makefile: Add rules to build and run tst-iconv7.c. * iconvdata/tst-iconv7.c: New test. --- libc/iconv/loop.c.jj 2007-12-10 09:05:32.000000000 +0100 +++ libc/iconv/loop.c 2008-01-08 11:50:52.000000000 +0100 @@ -1,5 +1,5 @@ /* Conversion loop frame work. - Copyright (C) 1998-2002, 2003, 2005 Free Software Foundation, Inc. + Copyright (C) 1998-2002, 2003, 2005, 2008 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1998. @@ -174,6 +174,15 @@ # define EXTRA_LOOP_DECLS #endif +/* Allow using UPDATE_PARAMS in macros where #ifdef UPDATE_PARAMS test + isn't possible. */ +#ifndef UPDATE_PARAMS +# define UPDATE_PARAMS do { } while (0) +#endif +#ifndef REINIT_PARAMS +# define REINIT_PARAMS do { } while (0) +#endif + /* To make it easier for the writers of the modules, we define a macro to test whether we have to ignore errors. */ @@ -214,6 +223,10 @@ case we are not doing any error recovery outself. */ \ break; \ \ + /* If needed, flush any conversion state, so that __gconv_transliterate \ + starts with current shift state. */ \ + UPDATE_PARAMS; \ + \ /* First try the transliteration methods. */ \ for (trans = step_data->__trans; trans != NULL; trans = trans->__next) \ { \ @@ -223,6 +236,9 @@ if (result != __GCONV_ILLEGAL_INPUT) \ break; \ } \ + \ + REINIT_PARAMS; \ + \ /* If any of them recognized the input continue with the loop. */ \ if (result != __GCONV_ILLEGAL_INPUT) \ { \ @@ -319,9 +335,7 @@ FCTNAME (LOOPFCT) (struct __gconv_step * /* Update the pointers pointed to by the parameters. */ *inptrp = inptr; *outptrp = outptr; -#ifdef UPDATE_PARAMS UPDATE_PARAMS; -#endif return result; } @@ -492,6 +506,7 @@ gconv_btowc (struct __gconv_step *step, #undef EXTRA_LOOP_DECLS #undef INIT_PARAMS #undef UPDATE_PARAMS +#undef REINIT_PARAMS #undef ONEBYTE_BODY #undef UNPACK_BYTES #undef CLEAR_STATE --- libc/iconvdata/iso-2022-jp.c.jj 2002-06-28 23:13:11.000000000 +0200 +++ libc/iconvdata/iso-2022-jp.c 2008-01-08 14:41:53.000000000 +0100 @@ -715,8 +715,7 @@ static const cvlist_t conversion_lists[4 list that depends on the current language tag. */ \ cvlist_t conversion_list; \ unsigned char buf[2]; \ - \ - result = __GCONV_ILLEGAL_INPUT; \ + int res = __GCONV_ILLEGAL_INPUT; \ \ if (var == iso2022jp2) \ conversion_list = conversion_lists[tag >> 8]; \ @@ -735,7 +734,7 @@ static const cvlist_t conversion_lists[4 { \ if (__builtin_expect (outptr + 3 > outend, 0)) \ { \ - result = __GCONV_FULL_OUTPUT; \ + res = __GCONV_FULL_OUTPUT; \ break; \ } \ *outptr++ = ESC; \ @@ -746,13 +745,13 @@ static const cvlist_t conversion_lists[4 \ if (__builtin_expect (outptr + 3 > outend, 0)) \ { \ - result = __GCONV_FULL_OUTPUT; \ + res = __GCONV_FULL_OUTPUT; \ break; \ } \ *outptr++ = ESC; \ *outptr++ = 'N'; \ *outptr++ = ch - 0x80; \ - result = __GCONV_OK; \ + res = __GCONV_OK; \ break; \ } \ \ @@ -774,7 +773,7 @@ static const cvlist_t conversion_lists[4 if (__builtin_expect (outptr + 3 > outend, \ 0)) \ { \ - result = __GCONV_FULL_OUTPUT; \ + res = __GCONV_FULL_OUTPUT; \ break; \ } \ *outptr++ = ESC; \ @@ -785,13 +784,13 @@ static const cvlist_t conversion_lists[4 \ if (__builtin_expect (outptr + 3 > outend, 0)) \ { \ - result = __GCONV_FULL_OUTPUT; \ + res = __GCONV_FULL_OUTPUT; \ break; \ } \ *outptr++ = ESC; \ *outptr++ = 'N'; \ *outptr++ = res; \ - result = __GCONV_OK; \ + res = __GCONV_OK; \ break; \ } \ } \ @@ -810,7 +809,7 @@ static const cvlist_t conversion_lists[4 { \ if (__builtin_expect (outptr + 3 > outend, 0)) \ { \ - result = __GCONV_FULL_OUTPUT; \ + res = __GCONV_FULL_OUTPUT; \ break; \ } \ *outptr++ = ESC; \ @@ -821,11 +820,11 @@ static const cvlist_t conversion_lists[4 \ if (__builtin_expect (outptr + 1 > outend, 0)) \ { \ - result = __GCONV_FULL_OUTPUT; \ + res = __GCONV_FULL_OUTPUT; \ break; \ } \ *outptr++ = buf[0]; \ - result = __GCONV_OK; \ + res = __GCONV_OK; \ break; \ } \ \ @@ -837,7 +836,7 @@ static const cvlist_t conversion_lists[4 { \ if (__builtin_expect (outptr + 3 > outend, 0)) \ { \ - result = __GCONV_FULL_OUTPUT; \ + res = __GCONV_FULL_OUTPUT; \ break; \ } \ *outptr++ = ESC; \ @@ -848,12 +847,12 @@ static const cvlist_t conversion_lists[4 \ if (__builtin_expect (outptr + 2 > outend, 0)) \ { \ - result = __GCONV_FULL_OUTPUT; \ + res = __GCONV_FULL_OUTPUT; \ break; \ } \ *outptr++ = buf[0]; \ *outptr++ = buf[1]; \ - result = __GCONV_OK; \ + res = __GCONV_OK; \ break; \ } \ \ @@ -869,7 +868,7 @@ static const cvlist_t conversion_lists[4 { \ if (__builtin_expect (outptr + 4 > outend, 0)) \ { \ - result = __GCONV_FULL_OUTPUT; \ + res = __GCONV_FULL_OUTPUT; \ break; \ } \ *outptr++ = ESC; \ @@ -881,12 +880,12 @@ static const cvlist_t conversion_lists[4 \ if (__builtin_expect (outptr + 2 > outend, 0)) \ { \ - result = __GCONV_FULL_OUTPUT; \ + res = __GCONV_FULL_OUTPUT; \ break; \ } \ *outptr++ = buf[0]; \ *outptr++ = buf[1]; \ - result = __GCONV_OK; \ + res = __GCONV_OK; \ break; \ } \ \ @@ -903,7 +902,7 @@ static const cvlist_t conversion_lists[4 { \ if (__builtin_expect (outptr + 3 > outend, 0)) \ { \ - result = __GCONV_FULL_OUTPUT; \ + res = __GCONV_FULL_OUTPUT; \ break; \ } \ *outptr++ = ESC; \ @@ -914,12 +913,12 @@ static const cvlist_t conversion_lists[4 \ if (__builtin_expect (outptr + 2 > outend, 0)) \ { \ - result = __GCONV_FULL_OUTPUT; \ + res = __GCONV_FULL_OUTPUT; \ break; \ } \ *outptr++ = buf[0]; \ *outptr++ = buf[1]; \ - result = __GCONV_OK; \ + res = __GCONV_OK; \ break; \ } \ \ @@ -936,7 +935,7 @@ static const cvlist_t conversion_lists[4 { \ if (__builtin_expect (outptr + 4 > outend, 0)) \ { \ - result = __GCONV_FULL_OUTPUT; \ + res = __GCONV_FULL_OUTPUT; \ break; \ } \ *outptr++ = ESC; \ @@ -948,12 +947,12 @@ static const cvlist_t conversion_lists[4 \ if (__builtin_expect (outptr + 2 > outend, 0)) \ { \ - result = __GCONV_FULL_OUTPUT; \ + res = __GCONV_FULL_OUTPUT; \ break; \ } \ *outptr++ = buf[0]; \ *outptr++ = buf[1]; \ - result = __GCONV_OK; \ + res = __GCONV_OK; \ break; \ } \ \ @@ -972,7 +971,7 @@ static const cvlist_t conversion_lists[4 { \ if (__builtin_expect (outptr + 3 > outend, 0)) \ { \ - result = __GCONV_FULL_OUTPUT; \ + res = __GCONV_FULL_OUTPUT; \ break; \ } \ *outptr++ = ESC; \ @@ -983,11 +982,11 @@ static const cvlist_t conversion_lists[4 \ if (__builtin_expect (outptr + 1 > outend, 0)) \ { \ - result = __GCONV_FULL_OUTPUT; \ + res = __GCONV_FULL_OUTPUT; \ break; \ } \ *outptr++ = buf[0] - 0x80; \ - result = __GCONV_OK; \ + res = __GCONV_OK; \ break; \ } \ \ @@ -996,13 +995,16 @@ static const cvlist_t conversion_lists[4 default: \ abort (); \ } \ - while (result == __GCONV_ILLEGAL_INPUT \ + while (res == __GCONV_ILLEGAL_INPUT \ && (conversion_list = CVLIST_REST (conversion_list)) != 0);\ \ - if (result == __GCONV_FULL_OUTPUT) \ - break; \ + if (res == __GCONV_FULL_OUTPUT) \ + { \ + result = res; \ + break; \ + } \ \ - if (result == __GCONV_ILLEGAL_INPUT) \ + if (res == __GCONV_ILLEGAL_INPUT) \ { \ STANDARD_TO_LOOP_ERR_HANDLER (4); \ } \ @@ -1017,6 +1019,13 @@ static const cvlist_t conversion_lists[4 #define INIT_PARAMS int set = *setp & CURRENT_SEL_MASK; \ int set2 = *setp & CURRENT_ASSIGN_MASK; \ int tag = *setp & CURRENT_TAG_MASK; +#define REINIT_PARAMS do \ + { \ + set = *setp & CURRENT_SEL_MASK; \ + set2 = *setp & CURRENT_ASSIGN_MASK; \ + tag = *setp & CURRENT_TAG_MASK; \ + } \ + while (0) #define UPDATE_PARAMS *setp = set | set2 | tag #include --- libc/iconvdata/ibm1364.c.jj 2005-10-20 01:31:17.000000000 +0200 +++ libc/iconvdata/ibm1364.c 2008-01-08 14:26:12.000000000 +0100 @@ -1,5 +1,5 @@ /* Conversion from and to IBM1364. - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2008 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Masahide Washizawa , 2005. @@ -387,6 +387,7 @@ enum #define LOOP_NEED_FLAGS #define EXTRA_LOOP_DECLS , int *curcsp #define INIT_PARAMS int curcs = *curcsp & ~7 +#define REINIT_PARAMS curcs = *curcsp & ~7 #define UPDATE_PARAMS *curcsp = curcs #include --- libc/iconvdata/ibm933.c.jj 2002-06-28 23:20:20.000000000 +0200 +++ libc/iconvdata/ibm933.c 2008-01-08 14:26:36.000000000 +0100 @@ -1,5 +1,5 @@ /* Conversion from and to IBM933. - Copyright (C) 2000-2002 Free Software Foundation, Inc. + Copyright (C) 2000-2002, 2008 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Masahide Washizawa , 2000. @@ -272,6 +272,7 @@ enum #define LOOP_NEED_FLAGS #define EXTRA_LOOP_DECLS , int *curcsp #define INIT_PARAMS int curcs = *curcsp & ~7 +#define REINIT_PARAMS curcs = *curcsp & ~7 #define UPDATE_PARAMS *curcsp = curcs #include --- libc/iconvdata/ibm937.c.jj 2002-06-28 23:21:25.000000000 +0200 +++ libc/iconvdata/ibm937.c 2008-01-08 14:26:55.000000000 +0100 @@ -1,5 +1,5 @@ /* Conversion from and to IBM937. - Copyright (C) 2000-2002 Free Software Foundation, Inc. + Copyright (C) 2000-2002, 2008 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Masahide Washizawa , 2000. @@ -272,6 +272,7 @@ enum #define LOOP_NEED_FLAGS #define EXTRA_LOOP_DECLS , int *curcsp #define INIT_PARAMS int curcs = *curcsp & ~7 +#define REINIT_PARAMS curcs = *curcsp & ~7 #define UPDATE_PARAMS *curcsp = curcs #include --- libc/iconvdata/iso-2022-jp-3.c.jj 2004-08-03 00:15:40.000000000 +0200 +++ libc/iconvdata/iso-2022-jp-3.c 2008-01-08 14:31:15.000000000 +0100 @@ -1,5 +1,6 @@ /* Conversion module for ISO-2022-JP-3. - Copyright (C) 1998-1999, 2000-2002, 2004 Free Software Foundation, Inc. + Copyright (C) 1998-1999, 2000-2002, 2004, 2008 + Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1998, and Bruno Haible , 2002. @@ -759,6 +760,12 @@ static const struct #define EXTRA_LOOP_DECLS , int *statep #define INIT_PARAMS int set = *statep & CURRENT_SEL_MASK; \ uint32_t lasttwo = *statep >> 6 +#define REINIT_PARAMS do \ + { \ + set = *statep & CURRENT_SEL_MASK; \ + lasttwo = *statep >> 6; \ + } \ + while (0) #define UPDATE_PARAMS *statep = set | (lasttwo << 6) #include --- libc/iconvdata/ibm930.c.jj 2002-06-28 23:19:37.000000000 +0200 +++ libc/iconvdata/ibm930.c 2008-01-08 14:26:26.000000000 +0100 @@ -1,5 +1,5 @@ /* Conversion from and to IBM930. - Copyright (C) 2000-2002 Free Software Foundation, Inc. + Copyright (C) 2000-2002, 2008 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Masahide Washizawa , 2000. @@ -277,6 +277,7 @@ enum #define LOOP_NEED_FLAGS #define EXTRA_LOOP_DECLS , int *curcsp #define INIT_PARAMS int curcs = *curcsp & ~7 +#define REINIT_PARAMS curcs = *curcsp & ~7 #define UPDATE_PARAMS *curcsp = curcs #include --- libc/iconvdata/ibm939.c.jj 2005-05-21 20:22:19.000000000 +0200 +++ libc/iconvdata/ibm939.c 2008-01-08 14:27:05.000000000 +0100 @@ -1,5 +1,5 @@ /* Conversion to and from IBM939. - Copyright (C) 2000-2002, 2005 Free Software Foundation, Inc. + Copyright (C) 2000-2002, 2005, 2008 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Masahide Washizawa , 2000. @@ -277,6 +277,7 @@ enum #define LOOP_NEED_FLAGS #define EXTRA_LOOP_DECLS , int *curcsp #define INIT_PARAMS int curcs = *curcsp & ~7 +#define REINIT_PARAMS curcs = *curcsp & ~7 #define UPDATE_PARAMS *curcsp = curcs #include --- libc/iconvdata/iso-2022-cn.c.jj 2007-08-27 14:17:18.000000000 +0200 +++ libc/iconvdata/iso-2022-cn.c 2008-01-08 14:29:07.000000000 +0100 @@ -1,5 +1,5 @@ /* Conversion module for ISO-2022-CN. - Copyright (C) 1999, 2000-2002, 2007 Free Software Foundation, Inc. + Copyright (C) 1999, 2000-2002, 2007, 2008 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1999. @@ -393,6 +393,12 @@ enum #define EXTRA_LOOP_DECLS , int *setp #define INIT_PARAMS int set = *setp & CURRENT_SEL_MASK; \ int ann = *setp & CURRENT_ANN_MASK +#define REINIT_PARAMS do \ + { \ + set = *setp & CURRENT_SEL_MASK; \ + ann = *setp & CURRENT_ANN_MASK; \ + } \ + while (0) #define UPDATE_PARAMS *setp = set | ann #include --- libc/iconvdata/iso-2022-cn-ext.c.jj 2007-07-29 11:45:13.000000000 +0200 +++ libc/iconvdata/iso-2022-cn-ext.c 2008-01-08 14:30:34.000000000 +0100 @@ -1,5 +1,5 @@ /* Conversion module for ISO-2022-CN-EXT. - Copyright (C) 2000-2002, 2004, 2007 Free Software Foundation, Inc. + Copyright (C) 2000-2002, 2004, 2007, 2008 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 2000. @@ -648,6 +648,12 @@ enum #define EXTRA_LOOP_DECLS , int *setp #define INIT_PARAMS int set = (*setp >> 3) & CURRENT_MASK; \ int ann = (*setp >> 3) & ~CURRENT_MASK +#define REINIT_PARAMS do \ + { \ + set = (*setp >> 3) & CURRENT_MASK; \ + ann = (*setp >> 3) & ~CURRENT_MASK; \ + } \ + while (0) #define UPDATE_PARAMS *setp = (set | ann) << 3 #define LOOP_NEED_FLAGS #include --- libc/iconvdata/ibm935.c.jj 2002-06-28 23:21:25.000000000 +0200 +++ libc/iconvdata/ibm935.c 2008-01-08 14:26:45.000000000 +0100 @@ -1,5 +1,5 @@ /* Conversion from and to IBM935 - Copyright (C) 2000-2002 Free Software Foundation, Inc. + Copyright (C) 2000-2002, 2008 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Masahide Washizawa , 2000. @@ -272,6 +272,7 @@ enum #define LOOP_NEED_FLAGS #define EXTRA_LOOP_DECLS , int *curcsp #define INIT_PARAMS int curcs = *curcsp & ~7 +#define REINIT_PARAMS curcs = *curcsp & ~7 #define UPDATE_PARAMS *curcsp = curcs #include --- libc/iconvdata/iso-2022-kr.c.jj 2007-08-27 14:17:18.000000000 +0200 +++ libc/iconvdata/iso-2022-kr.c 2008-01-08 14:31:31.000000000 +0100 @@ -1,5 +1,6 @@ /* Conversion module for ISO-2022-KR. - Copyright (C) 1998, 1999, 2000-2002, 2007 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2000-2002, 2007, 2008 + Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1998. @@ -261,6 +262,7 @@ enum #define LOOP_NEED_FLAGS #define EXTRA_LOOP_DECLS , int *setp #define INIT_PARAMS int set = *setp +#define REINIT_PARAMS set = *setp #define UPDATE_PARAMS *setp = set #include --- libc/iconvdata/tst-iconv7.c.jj 2008-01-08 13:47:36.000000000 +0100 +++ libc/iconvdata/tst-iconv7.c 2008-01-08 14:20:26.000000000 +0100 @@ -0,0 +1,61 @@ +#include +#include +#include +#include +#include + +static int +do_test (void) +{ + setlocale (LC_ALL, "de_DE.UTF-8"); + + iconv_t cd = iconv_open ("ISO-2022-JP//TRANSLIT", ""); + if (cd == (iconv_t) -1) + { + puts ("iconv_open failed"); + return 1; + } + + char instr1[] = "\xc2\xa3\xe2\x82\xac\n"; + const char expstr1[] = "\033$B!r\033(BEUR\n"; + char outstr[32]; + size_t inlen = sizeof (instr1); + size_t outlen = sizeof (outstr); + char *inptr = instr1; + char *outptr = outstr; + size_t r = iconv (cd, &inptr, &inlen, &outptr, &outlen); + if (r != 1 + || inlen != 0 + || outlen != sizeof (outstr) - sizeof (expstr1) + || memcmp (outstr, expstr1, sizeof (expstr1)) != 0) + { + puts ("wrong first conversion"); + return 1; + } + + char instr2[] = "\xe3\x88\xb1\n"; + const char expstr2[] = "(\033$B3t\033(B)\n"; + inlen = sizeof (instr2); + outlen = sizeof (outstr); + inptr = instr2; + outptr = outstr; + r = iconv (cd, &inptr, &inlen, &outptr, &outlen); + if (r != 1 + || inlen != 0 + || outlen != sizeof (outstr) - sizeof (expstr2) + || memcmp (outstr, expstr2, sizeof (expstr2)) != 0) + { + puts ("wrong second conversion"); + return 1; + } + + if (iconv_close (cd) != 0) + { + puts ("iconv_close failed"); + return 1; + } + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" --- libc/iconvdata/Makefile.jj 2007-12-12 20:14:00.000000000 +0100 +++ libc/iconvdata/Makefile 2008-01-08 14:17:57.000000000 +0100 @@ -1,4 +1,4 @@ -# Copyright (C) 1997-2004,2005,2006,2007 Free Software Foundation, Inc. +# Copyright (C) 1997-2004,2005,2006,2007,2008 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 @@ -67,7 +67,7 @@ include ../Makeconfig ifeq (yes,$(build-shared)) tests = bug-iconv1 bug-iconv2 tst-loading tst-e2big tst-iconv4 bug-iconv4 \ - tst-iconv6 bug-iconv5 bug-iconv6 + tst-iconv6 bug-iconv5 bug-iconv6 tst-iconv7 ifeq ($(have-thread-library),yes) tests += bug-iconv3 endif @@ -365,6 +365,8 @@ $(objpfx)tst-loading.out: $(objpfx)gconv $(addprefix $(objpfx),$(modules.so)) $(objpfx)tst-iconv4.out: $(objpfx)gconv-modules \ $(addprefix $(objpfx),$(modules.so)) +$(objpfx)tst-iconv7.out: $(objpfx)gconv-modules \ + $(addprefix $(objpfx),$(modules.so)) $(objpfx)iconv-test.out: run-iconv-test.sh $(objpfx)gconv-modules \ $(addprefix $(objpfx),$(modules.so)) \ Jakub