]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Fixes for parsing BODYSTRUCTURE
authorTimo Sirainen <tss@iki.fi>
Tue, 5 Aug 2003 23:10:33 +0000 (02:10 +0300)
committerTimo Sirainen <tss@iki.fi>
Tue, 5 Aug 2003 23:10:33 +0000 (02:10 +0300)
--HG--
branch : HEAD

src/lib-imap/imap-bodystructure.c
src/lib-imap/imap-parser.c
src/lib-imap/imap-parser.h

index 3f7b5c9d3b60c3943a552849ffd0d8253ecbe5b3..afa3f100d823268f30b9d79286ca715b41b5a438 100644 (file)
@@ -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
index 467a774cdff734bf2a403242e7ceda35965d417a..4782438a0b92a50818804c9f8bf562119beff104 100644 (file)
@@ -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;
index 331d59e2e8453bcdd933d086a8c1c482d6eec0b8..eb9f0a44f9b1f764b317c55a8f38b138033379be 100644 (file)
@@ -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);