From fd88b05dcfe189f6a93ddcdb431c73ef88feb136 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sun, 7 Sep 2008 23:18:24 +0200 Subject: [PATCH] Make striconveh work better with stateful encodings. --- ChangeLog | 6 ++++++ lib/striconveh.c | 31 ++++++++++++++++++++----------- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 56059f2a6..cc9e8a54b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2008-09-07 Bruno Haible + Make striconveh work better with stateful encodings. + * lib/striconveh.c (iconv_carefully, iconv_carefully_1): Don't assume + that iconv does not increment the inptr when returning -1/EINVAL. + +2008-09-07 Bruno Haible + * build-aux/config.rpath: Update according to libtool-2.2.6. * build-aux/config.libpath: Likewise. diff --git a/lib/striconveh.c b/lib/striconveh.c index 685117f81..10cb06f9d 100644 --- a/lib/striconveh.c +++ b/lib/striconveh.c @@ -79,9 +79,13 @@ iconv_carefully (iconv_t cd, &outptr, &outsize); if (!(res == (size_t)(-1) && errno == EINVAL)) break; - /* We expect that no input bytes have been consumed so far. */ - if (inptr != inptr_before) - abort (); + /* iconv can eat up a shift sequence but give EINVAL while attempting + to convert the first character. E.g. libiconv does this. */ + if (inptr > inptr_before) + { + res = 0; + break; + } } if (res == 0) @@ -117,31 +121,36 @@ iconv_carefully (iconv_t cd, # endif /* iconv_carefully_1 is like iconv_carefully, except that it stops after - converting one character. */ + converting one character or one shift sequence. */ static size_t iconv_carefully_1 (iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft, bool *incremented) { - const char *inptr = *inbuf; - const char *inptr_end = inptr + *inbytesleft; + const char *inptr_before = *inbuf; + const char *inptr = inptr_before; + const char *inptr_end = inptr_before + *inbytesleft; char *outptr = *outbuf; size_t outsize = *outbytesleft; - const char *inptr_before = inptr; size_t res = (size_t)(-1); size_t insize; - for (insize = 1; inptr + insize <= inptr_end; insize++) + for (insize = 1; inptr_before + insize <= inptr_end; insize++) { + inptr = inptr_before; res = iconv (cd, (ICONV_CONST char **) &inptr, &insize, &outptr, &outsize); if (!(res == (size_t)(-1) && errno == EINVAL)) break; - /* We expect that no input bytes have been consumed so far. */ - if (inptr != inptr_before) - abort (); + /* iconv can eat up a shift sequence but give EINVAL while attempting + to convert the first character. E.g. libiconv does this. */ + if (inptr > inptr_before) + { + res = 0; + break; + } } *inbuf = inptr; -- 2.11.0