]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-imap: imap_bodystructure_parse*() - Reset parts.data on failure
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Tue, 22 Feb 2022 16:44:02 +0000 (17:44 +0100)
committerMarco Bettini <marco.bettini@open-xchange.com>
Wed, 6 Jul 2022 13:41:47 +0000 (13:41 +0000)
Having the data filled only to some message_parts can confuse the callers,
thinking that all the parts were successfully filled.

Fixes:
Panic: file message-part-data.c: line 579 (message_part_is_attachment): assertion failed: (data != NULL)

src/lib-imap/imap-bodystructure.c
src/lib-imap/test-imap-bodystructure.c

index 522c2500676283d70cd0bbc3cb95ca44f4bebd2e..d4f42209f50993bb64e9789c72f43f9260b29f7c 100644 (file)
@@ -680,6 +680,15 @@ imap_bodystructure_parse_args(const struct imap_arg *args, pool_t pool,
                (part, pool, args, error_r);
 }
 
+
+static void imap_bodystructure_reset_data(struct message_part *parts)
+{
+       for (; parts != NULL; parts = parts->next) {
+               parts->data = NULL;
+               imap_bodystructure_reset_data(parts->children);
+       }
+}
+
 int imap_bodystructure_parse_full(const char *bodystructure,
        pool_t pool, struct message_part **parts,
        const char **error_r)
@@ -710,6 +719,13 @@ int imap_bodystructure_parse_full(const char *bodystructure,
                } T_END_PASS_STR_IF(ret < 0, error_r);
        }
 
+       if (ret < 0) {
+               /* Don't leave partially filled data to message_parts. Some of
+                  the code expects that if the first message_part->data is
+                  filled, they all are. */
+               imap_bodystructure_reset_data(*parts);
+       }
+
        imap_parser_unref(&parser);
        i_stream_destroy(&input);
        return ret;
index 6035118abd26594648a46f348749999ce57be4a6..736eb99f0ec58bc1babc85265b91d40516004c2c 100644 (file)
@@ -554,6 +554,7 @@ static void test_imap_bodystructure_parse_invalid(void)
                parts = msg_parse(pool, test->message, 0, 0, FALSE);
                test_assert_idx(imap_bodystructure_parse(test->bodystructure,
                                                         pool, parts, &error) == -1, i);
+               test_assert(parts->data == NULL);
                test_assert_strcmp_idx(error, test->error, i);
                pool_unref(&pool);
        } T_END;