dovecot: mailbox_keywords_create() checks keyword validity now a...
dovecot at dovecot.org
dovecot at dovecot.org
Sun Sep 2 06:10:58 EEST 2007
details: http://hg.dovecot.org/dovecot/rev/23c9ac999578
changeset: 6353:23c9ac999578
user: Timo Sirainen <tss at iki.fi>
date: Sun Sep 02 06:10:54 2007 +0300
description:
mailbox_keywords_create() checks keyword validity now and returns failure if
any of them are invalid. Added mailbox_keywords_create_valid() that only
drops invalid keywords. Removed mbox and IMAP-specific keyword checks, they
all use the same checking now.
diffstat:
14 files changed, 158 insertions(+), 98 deletions(-)
src/deliver/deliver.c | 2
src/imap/cmd-append.c | 9 ++
src/imap/cmd-copy.c | 2
src/imap/cmd-store.c | 10 ++-
src/imap/commands-util.c | 57 +++--------------
src/imap/common.h | 3
src/imap/main.c | 6 -
src/lib-storage/index/index-storage.c | 83 ++++++++++++++++++++++++--
src/lib-storage/index/index-storage.h | 8 +-
src/lib-storage/index/mbox/mbox-sync-parse.c | 18 -----
src/lib-storage/mail-storage-private.h | 10 +--
src/lib-storage/mail-storage.c | 34 +++++++++-
src/lib-storage/mail-storage.h | 11 ++-
src/plugins/convert/convert-storage.c | 3
diffs (truncated from 482 to 300 lines):
diff -r 0f1a4b7b39a3 -r 23c9ac999578 src/deliver/deliver.c
--- a/src/deliver/deliver.c Sun Sep 02 06:08:58 2007 +0300
+++ b/src/deliver/deliver.c Sun Sep 02 06:10:54 2007 +0300
@@ -142,7 +142,7 @@ int deliver_save(struct mail_namespace *
t = mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_EXTERNAL);
kw = strarray_length(keywords) == 0 ? NULL :
- mailbox_keywords_create(t, keywords);
+ mailbox_keywords_create_valid(t, keywords);
if (mailbox_copy(t, mail, flags, kw, NULL) < 0)
ret = -1;
mailbox_keywords_free(t, &kw);
diff -r 0f1a4b7b39a3 -r 23c9ac999578 src/imap/cmd-append.c
--- a/src/imap/cmd-append.c Sun Sep 02 06:08:58 2007 +0300
+++ b/src/imap/cmd-append.c Sun Sep 02 06:10:54 2007 +0300
@@ -290,8 +290,13 @@ static bool cmd_append_continue_parsing(
if (!client_parse_mail_flags(cmd, flags_list,
&flags, &keywords_list))
return cmd_append_cancel(ctx, nonsync);
- keywords = keywords_list == NULL ? NULL :
- mailbox_keywords_create(ctx->t, keywords_list);
+ if (keywords_list == NULL)
+ keywords = NULL;
+ else if (mailbox_keywords_create(ctx->t, keywords_list,
+ &keywords) < 0) {
+ client_send_storage_error(cmd, ctx->storage);
+ return cmd_append_cancel(ctx, nonsync);
+ }
} else {
flags = 0;
keywords = NULL;
diff -r 0f1a4b7b39a3 -r 23c9ac999578 src/imap/cmd-copy.c
--- a/src/imap/cmd-copy.c Sun Sep 02 06:08:58 2007 +0300
+++ b/src/imap/cmd-copy.c Sun Sep 02 06:10:54 2007 +0300
@@ -62,7 +62,7 @@ static int fetch_and_copy(struct client
keywords_list = mail_get_keywords(mail);
keywords = strarray_length(keywords_list) == 0 ? NULL :
- mailbox_keywords_create(t, keywords_list);
+ mailbox_keywords_create_valid(t, keywords_list);
if (mailbox_copy(t, mail, mail_get_flags(mail),
keywords, NULL) < 0)
ret = mail->expunged ? 0 : -1;
diff -r 0f1a4b7b39a3 -r 23c9ac999578 src/imap/cmd-store.c
--- a/src/imap/cmd-store.c Sun Sep 02 06:08:58 2007 +0300
+++ b/src/imap/cmd-store.c Sun Sep 02 06:10:54 2007 +0300
@@ -88,8 +88,14 @@ bool cmd_store(struct client_command_con
t = mailbox_transaction_begin(box, !silent ? 0 :
MAILBOX_TRANSACTION_FLAG_HIDE);
- keywords = keywords_list != NULL || modify_type == MODIFY_REPLACE ?
- mailbox_keywords_create(t, keywords_list) : NULL;
+ if (keywords_list == NULL && modify_type != MODIFY_REPLACE)
+ keywords = NULL;
+ else if (mailbox_keywords_create(t, keywords_list, &keywords) < 0) {
+ /* invalid keywords */
+ mailbox_transaction_rollback(&t);
+ client_send_storage_error(cmd, mailbox_get_storage(box));
+ return TRUE;
+ }
search_ctx = mailbox_search_init(t, NULL, search_arg, NULL);
mail = mail_alloc(t, MAIL_FETCH_FLAGS, NULL);
diff -r 0f1a4b7b39a3 -r 23c9ac999578 src/imap/commands-util.c
--- a/src/imap/commands-util.c Sun Sep 02 06:08:58 2007 +0300
+++ b/src/imap/commands-util.c Sun Sep 02 06:10:54 2007 +0300
@@ -189,45 +189,17 @@ void client_send_untagged_storage_error(
client_send_line(client, t_strconcat("* NO ", error_string, NULL));
}
-static bool is_valid_keyword(struct client_command_context *cmd,
- const char *keyword)
-{
- const char *const *names;
- unsigned int i, count;
-
- /* if it already exists, skip validity checks */
- if (array_is_created(&cmd->client->keywords.keywords)) {
- names = array_get(&cmd->client->keywords.keywords, &count);
- for (i = 0; i < count; i++) {
- if (strcasecmp(names[i], keyword) == 0)
- return TRUE;
- }
- }
-
- if (strlen(keyword) > max_keyword_length) {
- client_send_tagline(cmd,
- t_strdup_printf("BAD Invalid keyword name '%s': "
- "Maximum length is %u characters",
- keyword, max_keyword_length));
- return FALSE;
- }
-
- return TRUE;
-}
-
bool client_parse_mail_flags(struct client_command_context *cmd,
const struct imap_arg *args,
enum mail_flags *flags_r,
const char *const **keywords_r)
{
- const char *const *keywords;
const char *atom;
- buffer_t *buffer;
- size_t size, i;
+ ARRAY_DEFINE(keywords, const char *);
*flags_r = 0;
*keywords_r = NULL;
- buffer = buffer_create_dynamic(cmd->pool, 256);
+ p_array_init(&keywords, cmd->pool, 16);
while (args->type != IMAP_ARG_EOL) {
if (args->type != IMAP_ARG_ATOM) {
@@ -257,28 +229,19 @@ bool client_parse_mail_flags(struct clie
return FALSE;
}
} else {
- /* keyword - first make sure it's not a duplicate */
- keywords = buffer_get_data(buffer, &size);
- size /= sizeof(const char *);
- for (i = 0; i < size; i++) {
- if (strcasecmp(keywords[i], atom) == 0)
- break;
- }
-
- if (i == size) {
- if (!is_valid_keyword(cmd, atom))
- return FALSE;
- buffer_append(buffer, &atom, sizeof(atom));
- }
+ /* keyword validity checks are done by lib-storage */
+ array_append(&keywords, &atom, 1);
}
args++;
}
- atom = NULL;
- buffer_append(buffer, &atom, sizeof(atom));
- *keywords_r = buffer->used == sizeof(atom) ? NULL :
- buffer_get_data(buffer, NULL);
+ if (array_count(&keywords) == 0)
+ *keywords_r = NULL;
+ else {
+ (void)array_append_space(&keywords); /* NULL-terminate */
+ *keywords_r = array_idx(&keywords, 0);
+ }
return TRUE;
}
diff -r 0f1a4b7b39a3 -r 23c9ac999578 src/imap/common.h
--- a/src/imap/common.h Sun Sep 02 06:08:58 2007 +0300
+++ b/src/imap/common.h Sun Sep 02 06:10:54 2007 +0300
@@ -21,8 +21,6 @@
by default. */
#define DEFAULT_IMAP_MAX_LINE_LENGTH 65536
-#define DEFAULT_MAX_KEYWORD_LENGTH 50
-
enum client_workarounds {
WORKAROUND_DELAY_NEWMAIL = 0x01,
WORKAROUND_NETSCAPE_EOH = 0x04,
@@ -30,7 +28,6 @@ enum client_workarounds {
};
extern struct ioloop *ioloop;
-extern unsigned int max_keyword_length;
extern unsigned int imap_max_line_length;
extern enum client_workarounds client_workarounds;
extern const char *logout_format;
diff -r 0f1a4b7b39a3 -r 23c9ac999578 src/imap/main.c
--- a/src/imap/main.c Sun Sep 02 06:08:58 2007 +0300
+++ b/src/imap/main.c Sun Sep 02 06:10:54 2007 +0300
@@ -39,7 +39,6 @@ struct client_workaround_list client_wor
};
struct ioloop *ioloop;
-unsigned int max_keyword_length;
unsigned int imap_max_line_length;
enum client_workarounds client_workarounds = 0;
const char *logout_format;
@@ -225,11 +224,6 @@ static void main_init(void)
(unsigned int)strtoul(str, NULL, 10) :
DEFAULT_IMAP_MAX_LINE_LENGTH;
- str = getenv("MAIL_MAX_KEYWORD_LENGTH");
- max_keyword_length = str != NULL ?
- (unsigned int)strtoul(str, NULL, 10) :
- DEFAULT_MAX_KEYWORD_LENGTH;
-
logout_format = getenv("IMAP_LOGOUT_FORMAT");
if (logout_format == NULL)
logout_format = "bytes=%i/%o";
diff -r 0f1a4b7b39a3 -r 23c9ac999578 src/lib-storage/index/index-storage.c
--- a/src/lib-storage/index/index-storage.c Sun Sep 02 06:08:58 2007 +0300
+++ b/src/lib-storage/index/index-storage.c Sun Sep 02 06:10:54 2007 +0300
@@ -4,6 +4,7 @@
#include "array.h"
#include "buffer.h"
#include "ioloop.h"
+#include "imap-parser.h"
#include "mkdir-parents.h"
#include "mail-index-private.h"
#include "index-storage.h"
@@ -469,14 +470,86 @@ void mail_storage_set_index_error(struct
mail_index_reset_error(ibox->index);
}
-struct mail_keywords *
-index_keywords_create(struct mailbox_transaction_context *_t,
- const char *const keywords[])
+int index_mailbox_keyword_is_valid(struct index_mailbox *ibox,
+ const char *keyword, const char **error_r)
+{
+ unsigned int i, idx;
+
+ /* if it already exists, skip validity checks */
+ if (mail_index_keyword_lookup(ibox->index, keyword, &idx))
+ return TRUE;
+
+ if (*keyword == '\0') {
+ *error_r = "Empty keywords not allowed";
+ return FALSE;
+ }
+
+ /* these are IMAP-specific restrictions, but for now IMAP is all we
+ care about */
+ for (i = 0; keyword[i] != '\0'; i++) {
+ if (IS_ATOM_SPECIAL((unsigned char)keyword[i])) {
+ *error_r = "Invalid characters in keyword";
+ return FALSE;
+ }
+ if ((unsigned char)keyword[i] >= 0x80) {
+ *error_r = "8bit characters in keyword";
+ return FALSE;
+ }
+ }
+ if (i > ibox->box.storage->keyword_max_len) {
+ *error_r = "Keyword length too long";
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static struct mail_keywords *
+index_keywords_create_skip(struct index_transaction_context *t,
+ const char *const keywords[])
+{
+ ARRAY_DEFINE(valid_keywords, const char *);
+ struct mail_keywords *kw;
+ const char *error;
+
+ t_push();
+ t_array_init(&valid_keywords, 32);
+ for (; *keywords != NULL; keywords++) {
+ if (index_mailbox_keyword_is_valid(t->ibox, *keywords, &error))
+ array_append(&valid_keywords, keywords, 1);
+ }
+ (void)array_append_space(&valid_keywords); /* NULL-terminate */
+ kw = mail_index_keywords_create(t->trans, keywords);
+ t_pop();
+ return kw;
+}
+
+int index_keywords_create(struct mailbox_transaction_context *_t,
+ const char *const keywords[],
+ struct mail_keywords **keywords_r, bool skip_invalid)
{
struct index_transaction_context *t =
(struct index_transaction_context *)_t;
-
- return mail_index_keywords_create(t->trans, keywords);
+ const char *error;
+ unsigned int i;
+
+ for (i = 0; keywords[i] != NULL; i++) {
+ if (!index_mailbox_keyword_is_valid(t->ibox, keywords[i],
+ &error)) {
+ if (skip_invalid) {
+ /* found invalid keywords, do this the slow
+ way */
+ *keywords_r =
+ index_keywords_create_skip(t, keywords);
+ return 0;
+ }
+ mail_storage_set_error(t->ibox->box.storage,
+ MAIL_ERROR_PARAMS, error);
+ return -1;
+ }
+ }
+
+ *keywords_r = mail_index_keywords_create(t->trans, keywords);
+ return 0;
}
void index_keywords_free(struct mailbox_transaction_context *t __attr_unused__,
diff -r 0f1a4b7b39a3 -r 23c9ac999578 src/lib-storage/index/index-storage.h
--- a/src/lib-storage/index/index-storage.h Sun Sep 02 06:08:58 2007 +0300
+++ b/src/lib-storage/index/index-storage.h Sun Sep 02 06:10:54 2007 +0300
More information about the dovecot-cvs
mailing list