Mercurial > hg > octave-lojdl > gnulib-hg
changeset 10406:5991da96e696
Make striconveh work better with stateful encodings.
author | Bruno Haible <bruno@clisp.org> |
---|---|
date | Sun, 07 Sep 2008 23:18:24 +0200 |
parents | b1a4eae36771 |
children | 2575b6d4b6b5 |
files | ChangeLog lib/striconveh.c |
diffstat | 2 files changed, 26 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2008-09-07 Bruno Haible <bruno@clisp.org> + + 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 <bruno@clisp.org> * build-aux/config.rpath: Update according to libtool-2.2.6.
--- a/lib/striconveh.c +++ b/lib/striconveh.c @@ -79,9 +79,13 @@ &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 @@ # 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;