From: Timo Sirainen Date: Mon, 28 Feb 2011 17:52:10 +0000 (+0200) Subject: lib-charset: Skip over only invalid characters, not entire buffers around them. X-Git-Tag: 2.0.10~25 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9b0c832da64046a97ddadd57025d7859f537a552;p=thirdparty%2Fdovecot%2Fcore.git lib-charset: Skip over only invalid characters, not entire buffers around them. --- diff --git a/src/lib-charset/charset-iconv.c b/src/lib-charset/charset-iconv.c index b0ca3ce8bd..e71d6f3937 100644 --- a/src/lib-charset/charset-iconv.c +++ b/src/lib-charset/charset-iconv.c @@ -104,10 +104,7 @@ charset_to_utf8_try(struct charset_translation *t, 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 @@ charset_to_utf8(struct charset_translation *t, bool dtcase = (t->flags & CHARSET_FLAG_DECOMP_TITLECASE) != 0; enum charset_result result; size_t pos, used, size, prev_pos = 0, prev_used = 0; + size_t prev_invalid_pos = (size_t)-1; bool ret; for (pos = 0;;) { @@ -139,12 +137,17 @@ charset_to_utf8(struct charset_translation *t, ret = charset_to_utf8_try(t, src + pos, &size, dest, &result); pos += size; - if (ret) { - *src_size = pos; - return result; - } - - if (!dtcase) { + if (ret) + break; + + 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; @@ -156,6 +159,12 @@ charset_to_utf8(struct charset_translation *t, prev_used = dest->used; } } + + if (prev_invalid_pos != (size_t)-1) + result = CHARSET_RET_INVALID_INPUT; + + *src_size = pos; + return result; } #endif