X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fstriconveh.c;h=10cb06f9d65af1f4c065c49588c7d887cc9ac526;hb=2464bbfa7a6b82eca7bf3f7d517515ed462f1b23;hp=761f3b115b906b18b80d1ef1f9f22bd7f049cd60;hpb=53ddc721f3a7aa950d6503f51bfcb4314612d9b9;p=gnulib.git diff --git a/lib/striconveh.c b/lib/striconveh.c index 761f3b115..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; @@ -1017,7 +1026,11 @@ mem_iconveh (const char *src, size_t srclen, } } - if (STRCASEEQ (to_codeset, "UTF-8", 'U','T','F','-','8',0,0,0,0)) + if (STRCASEEQ (to_codeset, "UTF-8", 'U','T','F','-','8',0,0,0,0) +# if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2 || _LIBICONV_VERSION >= 0x0105 + || c_strcasecmp (to_codeset, "UTF-8//TRANSLIT") == 0 +# endif + ) cd2 = (iconv_t)(-1); else { @@ -1153,7 +1166,11 @@ str_iconveh (const char *src, } } - if (STRCASEEQ (to_codeset, "UTF-8", 'U','T','F','-','8',0,0,0,0)) + if (STRCASEEQ (to_codeset, "UTF-8", 'U','T','F','-','8',0,0,0,0) +# if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2 || _LIBICONV_VERSION >= 0x0105 + || c_strcasecmp (to_codeset, "UTF-8//TRANSLIT") == 0 +# endif + ) cd2 = (iconv_t)(-1); else {