Mercurial > dovecot > original-hg > dovecot-1.1
changeset 8370:9b17de31aac3 HEAD
lib-charset: Skip over only invalid characters, not entire buffers around them.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Fri, 04 Mar 2011 19:28:31 +0200 |
parents | 27a0fd89e181 |
children | 3698dfe0f21c |
files | src/lib-charset/charset-iconv.c |
diffstat | 1 files changed, 18 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-charset/charset-iconv.c Wed Sep 15 18:42:58 2010 +0100 +++ b/src/lib-charset/charset-iconv.c Fri Mar 04 19:28:31 2011 +0200 @@ -104,10 +104,7 @@ else { /* should be EILSEQ */ *result = CHARSET_RET_INVALID_INPUT; - if (!dtcase) - buffer_set_used_size(dest, dest->used - destleft); - uni_ucs4_to_utf8_c(UNICODE_REPLACEMENT_CHAR, dest); - return TRUE; + ret = FALSE; } *src_size -= srcleft; @@ -132,6 +129,7 @@ bool dtcase = (t->flags & CHARSET_FLAG_DECOMP_TITLECASE) != 0; enum charset_result result; size_t pos, used, size, prev_used = 0; + size_t prev_invalid_pos = (size_t)-1; bool ret; for (pos = 0;;) { @@ -139,12 +137,17 @@ ret = charset_to_utf8_try(t, src + pos, &size, dest, &result); pos += size; - if (ret) { - *src_size = pos; - return result; - } + if (ret) + break; - if (!dtcase) { + if (result == CHARSET_RET_INVALID_INPUT) { + if (prev_invalid_pos != dest->used) { + uni_ucs4_to_utf8_c(UNICODE_REPLACEMENT_CHAR, + dest); + prev_invalid_pos = dest->used; + } + pos++; + } else if (!dtcase) { /* force buffer to grow */ used = dest->used; size = buffer_get_size(dest) - used + 1; @@ -155,6 +158,12 @@ prev_used = dest->used; } } + + if (prev_invalid_pos != (size_t)-1) + result = CHARSET_RET_INVALID_INPUT; + + *src_size = pos; + return result; } #endif