Mercurial > dovecot > core-2.2
changeset 21310:8860c79510c5
lib-storage: Fix "*" in SEARCH seqset/uidset
4294967295 is used for "*", which matches the last existing message.
Which we don't know what it is at the time of search args simplification,
so avoid making any assumptions about it.
It's a bit ugly that 4294967295 can't be used as a valid UID, but this
restriction has already existed since the beginning of Dovecot. A future
alternative might be to add MAIL_SEARCH_ARG_FLAG_SEQSET_WITH_STAR, but
that's a bit complicated change.
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Thu, 15 Dec 2016 15:20:02 +0200 |
parents | d9493cd93820 |
children | 04ba3511d02a |
files | src/lib-storage/mail-search-args-simplify.c src/lib-storage/test-mail-search-args-simplify.c |
diffstat | 2 files changed, 25 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/mail-search-args-simplify.c Thu Dec 15 15:01:47 2016 +0200 +++ b/src/lib-storage/mail-search-args-simplify.c Thu Dec 15 15:20:02 2016 +0200 @@ -112,12 +112,17 @@ unsigned int count; if (args->match_not) { - /* invert the set to drop the NOT */ + /* invert the set to drop the NOT. Note that (uint32_t)-1 + matches the last existing mail, which we don't know at this + point. lib-imap/imap-seqset.c has similar code that + disallows using (uint32_t)-1 as a real UID. */ + if (seq_range_exists(&args->value.seqset, (uint32_t)-1)) + return; args->match_not = FALSE; - seq_range_array_invert(&args->value.seqset, 1, (uint32_t)-1); + seq_range_array_invert(&args->value.seqset, 1, (uint32_t)-2); } seqset = array_get(&args->value.seqset, &count); - if (count == 1 && seqset->seq1 == 1 && seqset->seq2 == (uint32_t)-1) { + if (count == 1 && seqset->seq1 == 1 && seqset->seq2 >= (uint32_t)-2) { /* 1:* is the same as ALL. */ args->type = SEARCH_ALL; } else if (count == 0) { @@ -134,7 +139,10 @@ struct mail_search_simplify_prev_arg mask; struct mail_search_arg **prev_argp; - i_assert(!args->match_not); + if (args->match_not) { + /* "*" used - can't simplify it */ + return FALSE; + } mail_search_arg_get_base_mask(args, &mask); prev_argp = mail_search_args_simplify_get_prev_argp(ctx, &mask);
--- a/src/lib-storage/test-mail-search-args-simplify.c Thu Dec 15 15:01:47 2016 +0200 +++ b/src/lib-storage/test-mail-search-args-simplify.c Thu Dec 15 15:20:02 2016 +0200 @@ -49,27 +49,34 @@ { "1:* 1:*", "ALL" }, { "OR 1:5 6:*", "ALL" }, + { "UID 1:* UID 1:*", "ALL" }, + { "OR UID 1:5 UID 6:*", "ALL" }, + { "2:* 2:*", "2:4294967295" }, { "OR 2:* 2:*", "2:4294967295" }, + { "UID 2:* UID 2:*", "UID 2:4294967295" }, + { "OR UID 2:* UID 2:*", "UID 2:4294967295" }, + { "1:5 6:7", "NOT ALL" }, { "1:5 3:7", "3:5" }, { "1:5 3:7 4:9", "4:5" }, { "1:5 OR 3:4 4:6", "3:5" }, { "OR 1 2", "1:2" }, - { "NOT 1,3:5", "2,6:4294967295" }, - { "NOT 1:100 NOT 50:200", "201:4294967295" }, - { "OR NOT 1:100 NOT 50:200", "1:49,101:4294967295" }, + { "NOT 1,3:5", "2,6:4294967294" }, + { "NOT 1:100 NOT 50:200", "201:4294967294" }, + { "OR NOT 1:100 NOT 50:200", "1:49,101:4294967294" }, { "UID 1:5 UID 6:7", "NOT ALL" }, { "UID 1:5 UID 3:7", "UID 3:5" }, { "OR UID 1 UID 2", "UID 1:2" }, - { "NOT UID 1,3:5", "UID 2,6:4294967295" }, + { "NOT UID 1,3:5", "UID 2,6:4294967294" }, { "1:5 UID 10:20", "1:5 UID 10:20" }, - { "1:5 NOT UID 10:20", "1:5 UID 1:9,21:4294967295" }, + { "1:5 NOT UID 10:20", "1:5 UID 1:9,21:4294967294" }, - { "ALL NOT UID 3:*", "UID 1:2" }, + { "ALL NOT UID 3:*", "NOT UID 3:4294967295" }, + { "NOT 1:10 NOT *", "11:4294967294 NOT 4294967295" }, { "BEFORE 03-Aug-2014 BEFORE 01-Aug-2014 BEFORE 02-Aug-2014", "BEFORE \"01-Aug-2014\"" }, { "OR BEFORE 01-Aug-2014 BEFORE 02-Aug-2014", "BEFORE \"02-Aug-2014\"" },