From: Timo Sirainen Date: Tue, 5 Aug 2003 23:10:33 +0000 (+0300) Subject: Fixes for parsing BODYSTRUCTURE X-Git-Tag: 1.1.alpha1~4445 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=de20c643fd37e6b592f69c22a926dd1b5a7edb76;p=thirdparty%2Fdovecot%2Fcore.git Fixes for parsing BODYSTRUCTURE --HG-- branch : HEAD --- diff --git a/src/lib-imap/imap-bodystructure.c b/src/lib-imap/imap-bodystructure.c index 3f7b5c9d3b..afa3f100d8 100644 --- a/src/lib-imap/imap-bodystructure.c +++ b/src/lib-imap/imap-bodystructure.c @@ -614,10 +614,6 @@ static int imap_parse_bodystructure_args(const struct imap_arg *args, str_append(str, " ("); subargs = IMAP_ARG_LIST(args)->args; for (; subargs->type != IMAP_ARG_EOL; ) { - if (subargs[0].type != IMAP_ARG_STRING || - subargs[1].type != IMAP_ARG_STRING) - return FALSE; - if (!str_append_imap_arg(str, &subargs[0])) return FALSE; str_append_c(str, ' '); @@ -695,9 +691,8 @@ const char *imap_body_parse_from_bodystructure(const char *bodystructure) (void)i_stream_read(input); parser = imap_parser_create(input, NULL, (size_t)-1); - ret = imap_parser_read_args(parser, 0, IMAP_PARSE_FLAG_NO_UNESCAPE | - IMAP_PARSE_FLAG_LITERAL_TYPE, &args); - + ret = imap_parser_finish_line(parser, 0, IMAP_PARSE_FLAG_NO_UNESCAPE | + IMAP_PARSE_FLAG_LITERAL_TYPE, &args); if (ret <= 0 || !imap_parse_bodystructure_args(args, str)) value = NULL; else diff --git a/src/lib-imap/imap-parser.c b/src/lib-imap/imap-parser.c index 467a774cdf..4782438a0b 100644 --- a/src/lib-imap/imap-parser.c +++ b/src/lib-imap/imap-parser.c @@ -563,6 +563,32 @@ static int imap_parser_read_arg(struct imap_parser *parser) ((parser)->cur_type != ARG_PARSE_NONE || \ (parser)->cur_list != parser->root_list) +static int finish_line(struct imap_parser *parser, unsigned int count, + struct imap_arg **args) +{ + parser->line_size += parser->cur_pos; + i_stream_skip(parser->input, parser->cur_pos); + parser->cur_pos = 0; + + if (parser->list_arg != NULL) { + parser->error = "Missing ')'"; + *args = NULL; + return -1; + } + + if (count >= parser->root_list->alloc) { + /* unused arguments must be NIL-filled. */ + parser->root_list = + LIST_REALLOC(parser, parser->root_list, count+1); + parser->root_list->alloc = count+1; + } + + parser->root_list->args[parser->root_list->size].type = IMAP_ARG_EOL; + + *args = parser->root_list->args; + return parser->root_list->size; +} + int imap_parser_read_args(struct imap_parser *parser, unsigned int count, enum imap_parser_flags flags, struct imap_arg **args) { @@ -589,29 +615,7 @@ int imap_parser_read_args(struct imap_parser *parser, unsigned int count, } else if ((!IS_UNFINISHED(parser) && count > 0 && parser->root_list->size >= count) || parser->eol) { /* all arguments read / end of line. */ - parser->line_size += parser->cur_pos; - i_stream_skip(parser->input, parser->cur_pos); - parser->cur_pos = 0; - - if (parser->list_arg != NULL) { - parser->error = "Missing ')'"; - *args = NULL; - return -1; - } - - if (count >= parser->root_list->alloc) { - /* unused arguments must be NIL-filled. */ - parser->root_list = LIST_REALLOC(parser, - parser->root_list, - count+1); - parser->root_list->alloc = count+1; - } - - parser->root_list->args[parser->root_list->size].type = - IMAP_ARG_EOL; - - *args = parser->root_list->args; - return parser->root_list->size; + return finish_line(parser, count, args); } else { /* need more data */ *args = NULL; @@ -619,6 +623,25 @@ int imap_parser_read_args(struct imap_parser *parser, unsigned int count, } } +int imap_parser_finish_line(struct imap_parser *parser, unsigned int count, + enum imap_parser_flags flags, + struct imap_arg **args) +{ + const unsigned char *data; + size_t data_size; + int ret; + + ret = imap_parser_read_args(parser, count, flags, args); + if (ret == -2) { + /* we should have noticed end of everything except atom */ + if (parser->cur_type == ARG_PARSE_ATOM) { + data = i_stream_get_data(parser->input, &data_size); + imap_parser_save_arg(parser, data, data_size); + } + } + return finish_line(parser, count, args); +} + const char *imap_parser_read_word(struct imap_parser *parser) { const unsigned char *data; diff --git a/src/lib-imap/imap-parser.h b/src/lib-imap/imap-parser.h index 331d59e2e8..eb9f0a44f9 100644 --- a/src/lib-imap/imap-parser.h +++ b/src/lib-imap/imap-parser.h @@ -95,6 +95,12 @@ const char *imap_parser_get_error(struct imap_parser *parser, int *fatal); int imap_parser_read_args(struct imap_parser *parser, unsigned int count, enum imap_parser_flags flags, struct imap_arg **args); +/* just like imap_parser_read_args(), but assume \n at end of data in + input stream. */ +int imap_parser_finish_line(struct imap_parser *parser, unsigned int count, + enum imap_parser_flags flags, + struct imap_arg **args); + /* Read one word - used for reading tag and command name. Returns NULL if more data is needed. */ const char *imap_parser_read_word(struct imap_parser *parser);