[dovecot-cvs] dovecot/src/lib-storage/index index-search.c,1.63,1.64
cras at procontrol.fi
cras at procontrol.fi
Mon Jan 13 23:29:11 EET 2003
Update of /home/cvs/dovecot/src/lib-storage/index
In directory danu:/tmp/cvs-serv1183/lib-storage/index
Modified Files:
index-search.c
Log Message:
SEARCH didn't properly complain about invalid messagesets. high:low never
worked (it was recently changed for other commands). "*" in UID set didn't
actually match for last uid, but last sequence number..
Index: index-search.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-search.c,v
retrieving revision 1.63
retrieving revision 1.64
diff -u -d -r1.63 -r1.64
--- index-search.c 11 Jan 2003 18:55:01 -0000 1.63
+++ index-search.c 13 Jan 2003 21:29:09 -0000 1.64
@@ -79,6 +79,9 @@
num = num*10 + (*set-'0');
set++;
}
+
+ if (num == 0)
+ return FALSE;
}
if (*set == ',' || *set == '\0') {
@@ -101,6 +104,17 @@
set++;
}
+ if (num2 == 0)
+ return FALSE;
+
+ if (num > num2) {
+ /* swap, as specified by latest
+ IMAP4rev1 draft */
+ unsigned int temp = num;
+ num = num2;
+ num2 = temp;
+ }
+
if (match_num >= num && match_num <= num2)
return TRUE;
}
@@ -167,7 +181,7 @@
ibox->synced_messages_count);
case SEARCH_UID:
return msgset_contains(value, rec->uid,
- ibox->synced_messages_count);
+ ibox->index->header->next_uid-1);
/* flags */
case SEARCH_ANSWERED:
@@ -651,10 +665,11 @@
return TRUE;
}
-static void seq_update(const char *set, unsigned int *first_seq,
- unsigned int *last_seq, unsigned int max_value)
+static int seq_update(const char *set, unsigned int *first_seq,
+ unsigned int *last_seq, unsigned int max_value)
{
unsigned int seq;
+ int first = TRUE;
while (*set != '\0') {
if (*set == '*') {
@@ -668,40 +683,64 @@
}
}
- if (seq != 0) {
- if (*first_seq == 0 || seq < *first_seq)
- *first_seq = seq;
- if (*last_seq == 0 || seq > *last_seq)
- *last_seq = seq;
- }
+ if (seq == 0)
+ return FALSE;
- set++;
+ if (*first_seq == 0 || seq < *first_seq)
+ *first_seq = seq;
+ if (*last_seq == 0 || seq > *last_seq)
+ *last_seq = seq;
+
+ if (*set != '\0') {
+ if (*set == ',')
+ first = TRUE;
+ else if (*set == ':' && first)
+ first = FALSE;
+ else
+ return FALSE;
+ set++;
+ }
}
+
+ return TRUE;
}
-static void search_get_sequid(struct index_mailbox *ibox,
- struct mail_search_arg *args,
- unsigned int *first_seq, unsigned int *last_seq,
- unsigned int *first_uid, unsigned int *last_uid)
+static int search_get_sequid(struct index_mailbox *ibox,
+ struct mail_search_arg *args,
+ unsigned int *first_seq, unsigned int *last_seq,
+ unsigned int *first_uid, unsigned int *last_uid)
{
for (; args != NULL; args = args->next) {
if (args->type == SEARCH_OR || args->type == SEARCH_SUB) {
- search_get_sequid(ibox, args->value.subargs,
- first_seq, last_seq,
- first_uid, last_uid);
+ if (!search_get_sequid(ibox, args->value.subargs,
+ first_seq, last_seq,
+ first_uid, last_uid))
+ return FALSE;
} if (args->type == SEARCH_SET) {
- seq_update(args->value.str, first_seq, last_seq,
- ibox->synced_messages_count);
+ if (!seq_update(args->value.str, first_seq, last_seq,
+ ibox->synced_messages_count)) {
+ mail_storage_set_error(ibox->box.storage,
+ "Invalid messageset: %s",
+ args->value.str);
+ return FALSE;
+ }
} else if (args->type == SEARCH_UID) {
- seq_update(args->value.str, first_uid, last_uid,
- ibox->index->header->next_uid-1);
+ if (!seq_update(args->value.str, first_uid, last_uid,
+ ibox->index->header->next_uid-1)) {
+ mail_storage_set_error(ibox->box.storage,
+ "Invalid messageset: %s",
+ args->value.str);
+ return FALSE;
+ }
} else if (args->type == SEARCH_ALL) {
/* go through everything */
*first_seq = 1;
*last_seq = ibox->synced_messages_count;
- return;
+ return TRUE;
}
}
+
+ return TRUE;
}
static int search_limit_by_flags(struct index_mailbox *ibox,
@@ -758,66 +797,75 @@
return *first_uid <= *last_uid;
}
-static unsigned int client_seq_to_uid(struct mail_index *index,
- unsigned int seq)
+static int client_seq_to_uid(struct index_mailbox *ibox,
+ unsigned int seq, unsigned int *uid)
{
struct mail_index_record *rec;
unsigned int expunges_before;
- (void)mail_modifylog_seq_get_expunges(index->modifylog, seq, seq,
+ if (seq > ibox->synced_messages_count) {
+ mail_storage_set_error(ibox->box.storage,
+ "Sequence out of range: %u", seq);
+ return FALSE;
+ }
+
+ (void)mail_modifylog_seq_get_expunges(ibox->index->modifylog, seq, seq,
&expunges_before);
seq -= expunges_before;
- rec = index->lookup(index, seq);
- return rec == NULL ? 0 : rec->uid;
+ rec = ibox->index->lookup(ibox->index, seq);
+ *uid = rec == NULL ? 0 : rec->uid;
+ return TRUE;
}
static int search_get_uid_range(struct index_mailbox *ibox,
struct mail_search_arg *args,
- unsigned int *first_uid,
- unsigned int *last_uid)
+ unsigned int *first_uid, unsigned int *last_uid)
{
unsigned int first_seq, last_seq, uid;
*first_uid = *last_uid = 0;
first_seq = last_seq = 0;
- search_get_sequid(ibox, args, &first_seq, &last_seq,
- first_uid, last_uid);
+ if (!search_get_sequid(ibox, args, &first_seq, &last_seq,
+ first_uid, last_uid))
+ return -1;
/* seq_update() should make sure that these can't happen */
i_assert(first_seq <= last_seq);
i_assert(*first_uid <= *last_uid);
if (first_seq > 1) {
- uid = client_seq_to_uid(ibox->index, first_seq);
+ if (!client_seq_to_uid(ibox, first_seq, &uid))
+ return -1;
if (uid == 0)
- return FALSE;
+ return 0;
if (*first_uid == 0 || uid < *first_uid)
*first_uid = uid;
}
if (last_seq > 1 && last_seq != ibox->synced_messages_count) {
- uid = client_seq_to_uid(ibox->index, last_seq);
+ if (!client_seq_to_uid(ibox, last_seq, &uid))
+ return -1;
if (uid == 0)
- return FALSE;
+ return 0;
- if (uid > *last_uid)
+ if (*last_uid == 0 || uid > *last_uid)
*last_uid = uid;
}
if (*first_uid == 0)
*first_uid = 1;
- if (*last_uid == 0)
+ if (*last_uid == 0 || last_seq == ibox->synced_messages_count)
*last_uid = ibox->index->header->next_uid-1;
/* UNSEEN and DELETED in root search level may limit the range */
if (!search_limit_by_flags(ibox, args, first_uid, last_uid))
- return FALSE;
+ return 0;
i_assert(*first_uid <= *last_uid);
- return TRUE;
+ return 1;
}
static int search_messages(struct index_mailbox *ibox, const char *charset,
@@ -839,8 +887,14 @@
return TRUE;
/* see if we can limit the records we look at */
- if (!search_get_uid_range(ibox, args, &first_uid, &last_uid))
+ switch (search_get_uid_range(ibox, args, &first_uid, &last_uid)) {
+ case -1:
+ /* error */
+ return FALSE;
+ case 0:
+ /* nothing found */
return TRUE;
+ }
rec = ibox->index->lookup_uid_range(ibox->index, first_uid, last_uid,
&client_seq);
More information about the dovecot-cvs
mailing list