diff options
Diffstat (limited to 'lib/libiconv_modules/iconv_std/citrus_iconv_std.c')
-rw-r--r-- | lib/libiconv_modules/iconv_std/citrus_iconv_std.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/lib/libiconv_modules/iconv_std/citrus_iconv_std.c b/lib/libiconv_modules/iconv_std/citrus_iconv_std.c index ec9f21de541e..8eb9f6f7c5ba 100644 --- a/lib/libiconv_modules/iconv_std/citrus_iconv_std.c +++ b/lib/libiconv_modules/iconv_std/citrus_iconv_std.c @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ /* $NetBSD: citrus_iconv_std.c,v 1.16 2012/02/12 13:51:29 wiz Exp $ */ /*- @@ -472,7 +471,7 @@ _citrus_iconv_std_iconv_convert(struct _citrus_iconv * __restrict cv, _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 +503,8 @@ _citrus_iconv_std_iconv_convert(struct _citrus_iconv * __restrict cv, return (0); } + in_mb_cur_min = _stdenc_get_mb_cur_min(is->is_src_encoding); + /* normal case */ for (;;) { if (*inbytes == 0) { @@ -522,8 +523,20 @@ _citrus_iconv_std_iconv_convert(struct _citrus_iconv * __restrict cv, 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 */ |