dovecot-2.2: imap_body_parse_from_bodystructure() now returns th...
dovecot at dovecot.org
dovecot at dovecot.org
Sat Sep 15 16:13:09 EEST 2012
details: http://hg.dovecot.org/dovecot-2.2/rev/6acd8b149709
changeset: 15056:6acd8b149709
user: Timo Sirainen <tss at iki.fi>
date: Sat Sep 15 16:13:02 2012 +0300
description:
imap_body_parse_from_bodystructure() now returns the error instead of logging it.
diffstat:
src/lib-imap/imap-bodystructure.c | 119 ++++++++++++++++++++++--------------
src/lib-imap/imap-bodystructure.h | 7 +-
src/lib-storage/index/index-mail.c | 10 ++-
3 files changed, 82 insertions(+), 54 deletions(-)
diffs (271 lines):
diff -r c436a6c3f7d2 -r 6acd8b149709 src/lib-imap/imap-bodystructure.c
--- a/src/lib-imap/imap-bodystructure.c Sat Sep 15 15:46:01 2012 +0300
+++ b/src/lib-imap/imap-bodystructure.c Sat Sep 15 16:13:02 2012 +0300
@@ -533,7 +533,7 @@
}
}
-static bool str_append_imap_arg(string_t *str, const struct imap_arg *arg)
+static bool str_append_nstring(string_t *str, const struct imap_arg *arg)
{
const char *cstr;
@@ -566,19 +566,20 @@
return TRUE;
}
-static bool imap_write_list(const struct imap_arg *args, string_t *str)
+static void imap_write_list(const struct imap_arg *args, string_t *str)
{
const struct imap_arg *children;
/* don't do any typechecking, just write it out */
str_append_c(str, '(');
while (!IMAP_ARG_IS_EOL(args)) {
- if (!str_append_imap_arg(str, args)) {
- if (!imap_arg_get_list(args, &children))
- return FALSE;
+ if (!str_append_nstring(str, args)) {
+ if (!imap_arg_get_list(args, &children)) {
+ /* everything is either nstring or list */
+ i_unreached();
+ }
- if (!imap_write_list(children, str))
- return FALSE;
+ imap_write_list(children, str);
}
args++;
@@ -586,11 +587,10 @@
str_append_c(str, ' ');
}
str_append_c(str, ')');
- return TRUE;
}
-static bool imap_parse_bodystructure_args(const struct imap_arg *args,
- string_t *str)
+static int imap_parse_bodystructure_args(const struct imap_arg *args,
+ string_t *str, const char **error_r)
{
const struct imap_arg *subargs;
const struct imap_arg *list_args;
@@ -602,8 +602,8 @@
while (args->type == IMAP_ARG_LIST) {
str_append_c(str, '(');
list_args = imap_arg_as_list(args);
- if (!imap_parse_bodystructure_args(list_args, str))
- return FALSE;
+ if (imap_parse_bodystructure_args(list_args, str, error_r) < 0)
+ return -1;
str_append_c(str, ')');
multipart = TRUE;
@@ -613,19 +613,25 @@
if (multipart) {
/* next is subtype of Content-Type. rest is skipped. */
str_append_c(str, ' ');
- return str_append_imap_arg(str, args);
+ if (!str_append_nstring(str, args)) {
+ *error_r = "Invalid multipart content-type";
+ return -1;
+ }
+ return 0;
}
/* "content type" "subtype" */
if (!imap_arg_get_astring(&args[0], &content_type) ||
- !imap_arg_get_astring(&args[1], &subtype))
- return FALSE;
+ !imap_arg_get_astring(&args[1], &subtype)) {
+ *error_r = "Invalid content-type";
+ return -1;
+ }
- if (!str_append_imap_arg(str, &args[0]))
- return FALSE;
+ if (!str_append_nstring(str, &args[0]))
+ i_unreached();
str_append_c(str, ' ');
- if (!str_append_imap_arg(str, &args[1]))
- return FALSE;
+ if (!str_append_nstring(str, &args[1]))
+ i_unreached();
text = strcasecmp(content_type, "text") == 0;
message_rfc822 = strcasecmp(content_type, "message") == 0 &&
@@ -637,11 +643,15 @@
if (imap_arg_get_list(args, &subargs)) {
str_append(str, " (");
while (!IMAP_ARG_IS_EOL(subargs)) {
- if (!str_append_imap_arg(str, &subargs[0]))
- return FALSE;
+ if (!str_append_nstring(str, &subargs[0])) {
+ *error_r = "Invalid content param key";
+ return -1;
+ }
str_append_c(str, ' ');
- if (!str_append_imap_arg(str, &subargs[1]))
- return FALSE;
+ if (!str_append_nstring(str, &subargs[1])) {
+ *error_r = "Invalid content param value";
+ return -1;
+ }
subargs += 2;
if (IMAP_ARG_IS_EOL(subargs))
@@ -652,7 +662,8 @@
} else if (args->type == IMAP_ARG_NIL) {
str_append(str, " NIL");
} else {
- return FALSE;
+ *error_r = "list/NIL expected";
+ return -1;
}
args++;
@@ -660,14 +671,18 @@
for (i = 0; i < 4; i++, args++) {
str_append_c(str, ' ');
- if (!str_append_imap_arg(str, args))
- return FALSE;
+ if (!str_append_nstring(str, args)) {
+ *error_r = "nstring expected";
+ return -1;
+ }
}
if (text) {
/* text/xxx - text lines */
- if (!imap_arg_get_atom(args, &value))
- return FALSE;
+ if (!imap_arg_get_atom(args, &value)) {
+ *error_r = "Text lines expected";
+ return -1;
+ }
str_append_c(str, ' ');
str_append(str, value);
@@ -675,33 +690,37 @@
/* message/rfc822 - envelope + bodystructure + text lines */
str_append_c(str, ' ');
- if (!imap_arg_get_list(&args[0], &list_args))
- return FALSE;
- if (!imap_write_list(list_args, str))
- return FALSE;
-
+ if (!imap_arg_get_list(&args[0], &list_args)) {
+ *error_r = "Envelope list expected";
+ return -1;
+ }
+ imap_write_list(list_args, str);
str_append(str, " (");
- if (!imap_arg_get_list(&args[1], &list_args))
- return FALSE;
- if (!imap_parse_bodystructure_args(list_args, str))
- return FALSE;
+ if (!imap_arg_get_list(&args[1], &list_args)) {
+ *error_r = "Child bodystructure list expected";
+ return -1;
+ }
+ if (imap_parse_bodystructure_args(list_args, str, error_r) < 0)
+ return -1;
str_append(str, ") ");
- if (!imap_arg_get_atom(&args[2], &value))
- return FALSE;
+ if (!imap_arg_get_atom(&args[2], &value)) {
+ *error_r = "Text lines expected";
+ return -1;
+ }
str_append(str, value);
}
-
- return TRUE;
+ return 0;
}
-bool imap_body_parse_from_bodystructure(const char *bodystructure,
- string_t *dest)
+int imap_body_parse_from_bodystructure(const char *bodystructure,
+ string_t *dest, const char **error_r)
{
struct istream *input;
struct imap_parser *parser;
const struct imap_arg *args;
+ bool fatal;
int ret;
input = i_stream_create_from_data(bodystructure, strlen(bodystructure));
@@ -710,12 +729,16 @@
parser = imap_parser_create(input, NULL, (size_t)-1);
ret = imap_parser_finish_line(parser, 0, IMAP_PARSE_FLAG_NO_UNESCAPE |
IMAP_PARSE_FLAG_LITERAL_TYPE, &args);
- ret = ret > 0 && imap_parse_bodystructure_args(args, dest);
-
- if (!ret)
- i_error("Error parsing IMAP bodystructure: %s", bodystructure);
+ if (ret < 0) {
+ *error_r = t_strdup_printf("IMAP parser failed: %s",
+ imap_parser_get_error(parser, &fatal));
+ } else if (ret == 0) {
+ *error_r = "Empty bodystructure";
+ } else {
+ ret = imap_parse_bodystructure_args(args, dest, error_r);
+ }
imap_parser_unref(&parser);
i_stream_destroy(&input);
- return ret;
+ return ret <= 0 ? -1 : 0;
}
diff -r c436a6c3f7d2 -r 6acd8b149709 src/lib-imap/imap-bodystructure.h
--- a/src/lib-imap/imap-bodystructure.h Sat Sep 15 15:46:01 2012 +0300
+++ b/src/lib-imap/imap-bodystructure.h Sat Sep 15 16:13:02 2012 +0300
@@ -16,8 +16,9 @@
void imap_bodystructure_write(const struct message_part *part,
string_t *dest, bool extended);
-/* Return BODY part from BODYSTRUCTURE */
-bool imap_body_parse_from_bodystructure(const char *bodystructure,
- string_t *dest);
+/* Get BODY part from BODYSTRUCTURE and write it to dest.
+ Returns 0 if ok, -1 if bodystructure wasn't valid. */
+int imap_body_parse_from_bodystructure(const char *bodystructure,
+ string_t *dest, const char **error_r);
#endif
diff -r c436a6c3f7d2 -r 6acd8b149709 src/lib-storage/index/index-mail.c
--- a/src/lib-storage/index/index-mail.c Sat Sep 15 15:46:01 2012 +0300
+++ b/src/lib-storage/index/index-mail.c Sat Sep 15 16:13:02 2012 +0300
@@ -1035,6 +1035,7 @@
struct index_mail *mail = (struct index_mail *)_mail;
struct index_mail_data *data = &mail->data;
const struct mail_cache_field *cache_fields = mail->ibox->cache_fields;
+ const char *error;
string_t *str;
switch (field) {
@@ -1071,12 +1072,15 @@
str_truncate(str, 0);
if (imap_body_parse_from_bodystructure(
- data->bodystructure, str))
- data->body = str_c(str);
- else {
+ data->bodystructure, str, &error) < 0) {
/* broken, continue.. */
+ mail_storage_set_critical(_mail->box->storage,
+ "Invalid BODYSTRUCTURE %s: %s",
+ data->bodystructure, error);
mail_set_cache_corrupted(_mail,
MAIL_FETCH_IMAP_BODYSTRUCTURE);
+ } else {
+ data->body = str_c(str);
}
}
More information about the dovecot-cvs
mailing list