diff --git a/lib/libiconv_modules/iconv_std/citrus_iconv_std.c b/lib/libiconv_modules/iconv_std/citrus_iconv_std.c --- a/lib/libiconv_modules/iconv_std/citrus_iconv_std.c +++ b/lib/libiconv_modules/iconv_std/citrus_iconv_std.c @@ -472,7 +472,7 @@ _csid_t csid; _index_t idx; char *tmpin; - size_t inval, szrin, szrout; + size_t inval, in_mb_cur_min, szrin, szrout; int ret, state = 0; inval = 0; @@ -504,6 +504,8 @@ return (0); } + in_mb_cur_min = _stdenc_get_mb_cur_min(is->is_src_encoding); + /* normal case */ for (;;) { if (*inbytes == 0) { @@ -522,8 +524,20 @@ szrin = szrout = 0; ret = mbtocsx(&sc->sc_src_encoding, &csid, &idx, &tmpin, *inbytes, &szrin, cv->cv_shared->ci_hooks); - if (ret) + if (ret != 0 && (ret != EILSEQ || + !cv->cv_shared->ci_discard_ilseq)) { goto err; + } else if (ret == EILSEQ) { + /* + * If //IGNORE was specified, we'll just keep crunching + * through invalid characters. + */ + *in += in_mb_cur_min; + *inbytes -= in_mb_cur_min; + restore_encoding_state(&sc->sc_src_encoding); + restore_encoding_state(&sc->sc_dst_encoding); + continue; + } if (szrin == (size_t)-2) { /* incompleted character */