Mercurial > dovecot > core-2.2
changeset 21449:3909e522e8af
lib-fts: Fix assert-crash in fts_icu_lcase()
Fixes:
Panic: file fts-icu.c: line 152 (fts_icu_lcase): assertion failed: (err != U_BUFFER_OVERFLOW_ERROR)
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Tue, 24 Jan 2017 17:18:07 +0200 |
parents | 66253aee7ebf |
children | 5ca3a3f11254 |
files | src/lib-fts/fts-icu.c src/lib-fts/test-fts-icu.c |
diffstat | 2 files changed, 20 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-fts/fts-icu.c Fri Jan 27 09:41:36 2017 +0200 +++ b/src/lib-fts/fts-icu.c Tue Jan 24 17:18:07 2017 +0200 @@ -142,14 +142,17 @@ avail_bytes = buffer_get_writable_size(dest_utf8) - dest_pos; dest_data = buffer_get_space_unsafe(dest_utf8, dest_pos, avail_bytes); - dest_full_len = ucasemap_utf8ToLower(csm, dest_data, avail_bytes, - src_utf8, -1, &err); - if (err == U_BUFFER_OVERFLOW_ERROR) { + /* ucasemap_utf8ToLower() may need to be called multiple times, because + the first return value may not be large enough. */ + for (unsigned int i = 0;; i++) { + dest_full_len = ucasemap_utf8ToLower(csm, dest_data, avail_bytes, + src_utf8, -1, &err); + if (err != U_BUFFER_OVERFLOW_ERROR || i == 2) + break; + err = U_ZERO_ERROR; dest_data = buffer_get_space_unsafe(dest_utf8, dest_pos, dest_full_len); - dest_full_len = ucasemap_utf8ToLower(csm, dest_data, dest_full_len, - src_utf8, -1, &err); - i_assert(err != U_BUFFER_OVERFLOW_ERROR); + avail_bytes = dest_full_len; } if (U_FAILURE(err)) { i_fatal("LibICU ucasemap_utf8ToLower() failed: %s",
--- a/src/lib-fts/test-fts-icu.c Fri Jan 27 09:41:36 2017 +0200 +++ b/src/lib-fts/test-fts-icu.c Tue Jan 24 17:18:07 2017 +0200 @@ -169,6 +169,16 @@ test_end(); } +static void test_fts_icu_lcase_resize_invalid_utf8(void) +{ + string_t *dest; + + test_begin("fts_icu_lcase resize invalid utf8"); + dest = t_str_new(1); + fts_icu_lcase(dest, ".\x80."); + test_end(); +} + int main(void) { static void (*test_functions[])(void) = { @@ -180,6 +190,7 @@ test_fts_icu_translate_resize, test_fts_icu_lcase, test_fts_icu_lcase_resize, + test_fts_icu_lcase_resize_invalid_utf8, NULL }; int ret = test_run(test_functions);