Mercurial > dovecot > core-2.2
annotate src/lib-imap/imap-parser.c @ 22955:812e5c961328
fts: Indexing virtual mailbox didn't always index the last mails
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Thu, 03 May 2018 18:33:00 +0300 |
parents | cb108f786fb4 |
children | ae4659f289a9 |
rev | line source |
---|---|
22713
cb108f786fb4
Updated copyright notices to include the year 2018.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents:
22050
diff
changeset
|
1 /* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */ |
0 | 2 |
3 #include "lib.h" | |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
735
diff
changeset
|
4 #include "istream.h" |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
735
diff
changeset
|
5 #include "ostream.h" |
896
21ffcce83c70
Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
877
diff
changeset
|
6 #include "strescape.h" |
0 | 7 #include "imap-parser.h" |
8 | |
15245
42f99a4fc763
lib-imap: Changed public IS_ATOM*() macros to match RFC 3501 exactly.
Timo Sirainen <tss@iki.fi>
parents:
15162
diff
changeset
|
9 /* We use this macro to read atoms from input. It should probably contain |
42f99a4fc763
lib-imap: Changed public IS_ATOM*() macros to match RFC 3501 exactly.
Timo Sirainen <tss@iki.fi>
parents:
15162
diff
changeset
|
10 everything some day, but for now we can't handle some input otherwise: |
42f99a4fc763
lib-imap: Changed public IS_ATOM*() macros to match RFC 3501 exactly.
Timo Sirainen <tss@iki.fi>
parents:
15162
diff
changeset
|
11 |
42f99a4fc763
lib-imap: Changed public IS_ATOM*() macros to match RFC 3501 exactly.
Timo Sirainen <tss@iki.fi>
parents:
15162
diff
changeset
|
12 ']' is required for parsing section (FETCH BODY[]) |
42f99a4fc763
lib-imap: Changed public IS_ATOM*() macros to match RFC 3501 exactly.
Timo Sirainen <tss@iki.fi>
parents:
15162
diff
changeset
|
13 '%', '*' and ']' are valid list-chars for LIST patterns |
42f99a4fc763
lib-imap: Changed public IS_ATOM*() macros to match RFC 3501 exactly.
Timo Sirainen <tss@iki.fi>
parents:
15162
diff
changeset
|
14 '\' is used in flags */ |
42f99a4fc763
lib-imap: Changed public IS_ATOM*() macros to match RFC 3501 exactly.
Timo Sirainen <tss@iki.fi>
parents:
15162
diff
changeset
|
15 #define IS_ATOM_PARSER_INPUT(c) \ |
42f99a4fc763
lib-imap: Changed public IS_ATOM*() macros to match RFC 3501 exactly.
Timo Sirainen <tss@iki.fi>
parents:
15162
diff
changeset
|
16 ((c) == '(' || (c) == ')' || (c) == '{' || \ |
42f99a4fc763
lib-imap: Changed public IS_ATOM*() macros to match RFC 3501 exactly.
Timo Sirainen <tss@iki.fi>
parents:
15162
diff
changeset
|
17 (c) == '"' || (c) <= 32 || (c) == 0x7f) |
42f99a4fc763
lib-imap: Changed public IS_ATOM*() macros to match RFC 3501 exactly.
Timo Sirainen <tss@iki.fi>
parents:
15162
diff
changeset
|
18 |
0 | 19 #define is_linebreak(c) \ |
20 ((c) == '\r' || (c) == '\n') | |
21 | |
5836
9f869a7a3d73
Changed imap-parser API to use standard arrays for lists instead of its own
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
22 #define LIST_INIT_COUNT 7 |
444
85ab93a7693b
ImapArgList changed from linked list to array. easier to handle that way.
Timo Sirainen <tss@iki.fi>
parents:
424
diff
changeset
|
23 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
24 enum arg_parse_type { |
0 | 25 ARG_PARSE_NONE = 0, |
26 ARG_PARSE_ATOM, | |
27 ARG_PARSE_STRING, | |
28 ARG_PARSE_LITERAL, | |
14607
68a8b650578e
imap parser: Added support for parsing literal8 (for BINARY extension)
Timo Sirainen <tss@iki.fi>
parents:
14589
diff
changeset
|
29 ARG_PARSE_LITERAL8, |
6739
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
30 ARG_PARSE_LITERAL_DATA, |
15129
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
31 ARG_PARSE_LITERAL_DATA_FORCED, |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
32 ARG_PARSE_TEXT |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
33 }; |
0 | 34 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
35 struct imap_parser { |
444
85ab93a7693b
ImapArgList changed from linked list to array. easier to handle that way.
Timo Sirainen <tss@iki.fi>
parents:
424
diff
changeset
|
36 /* permanent */ |
13627
f63f2b2217c3
lib-imap: Added reference counting to imap parser.
Timo Sirainen <tss@iki.fi>
parents:
12860
diff
changeset
|
37 int refcount; |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
38 pool_t pool; |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
39 struct istream *input; |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
40 struct ostream *output; |
1591
6eca99b727a0
IMAP parser memory limits are now enforced by bytes per line rather than
Timo Sirainen <tss@iki.fi>
parents:
1311
diff
changeset
|
41 size_t max_line_size; |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
42 enum imap_parser_flags flags; |
0 | 43 |
444
85ab93a7693b
ImapArgList changed from linked list to array. easier to handle that way.
Timo Sirainen <tss@iki.fi>
parents:
424
diff
changeset
|
44 /* reset by imap_parser_reset(): */ |
1591
6eca99b727a0
IMAP parser memory limits are now enforced by bytes per line rather than
Timo Sirainen <tss@iki.fi>
parents:
1311
diff
changeset
|
45 size_t line_size; |
5836
9f869a7a3d73
Changed imap-parser API to use standard arrays for lists instead of its own
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
46 ARRAY_TYPE(imap_arg_list) root_list; |
9f869a7a3d73
Changed imap-parser API to use standard arrays for lists instead of its own
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
47 ARRAY_TYPE(imap_arg_list) *cur_list; |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
48 struct imap_arg *list_arg; |
0 | 49 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
50 enum arg_parse_type cur_type; |
502
7927650f3b9b
imap_parser_read_args() didn't correctly always return "need for more data"
Timo Sirainen <tss@iki.fi>
parents:
469
diff
changeset
|
51 size_t cur_pos; /* parser position in input buffer */ |
15129
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
52 bool cur_resp_text; /* we're parsing [resp-text-code] */ |
0 | 53 |
54 int str_first_escape; /* ARG_PARSE_STRING: index to first '\' */ | |
50
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
55 uoff_t literal_size; /* ARG_PARSE_LITERAL: string size */ |
444
85ab93a7693b
ImapArgList changed from linked list to array. easier to handle that way.
Timo Sirainen <tss@iki.fi>
parents:
424
diff
changeset
|
56 |
768
8b3518bb327e
Limited max. command argument elements to 128. Added more verbose error
Timo Sirainen <tss@iki.fi>
parents:
764
diff
changeset
|
57 const char *error; |
8b3518bb327e
Limited max. command argument elements to 128. Added more verbose error
Timo Sirainen <tss@iki.fi>
parents:
764
diff
changeset
|
58 |
0 | 59 unsigned int literal_skip_crlf:1; |
1022
09bac2875ed8
Support for LITERAL+ extension.
Timo Sirainen <tss@iki.fi>
parents:
1014
diff
changeset
|
60 unsigned int literal_nonsync:1; |
14607
68a8b650578e
imap parser: Added support for parsing literal8 (for BINARY extension)
Timo Sirainen <tss@iki.fi>
parents:
14589
diff
changeset
|
61 unsigned int literal8:1; |
6739
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
62 unsigned int literal_size_return:1; |
0 | 63 unsigned int eol:1; |
14979
e0a3812771fd
imap-parser: Allow calling imap_parser_read_args() multiple times with larger count parameter.
Timo Sirainen <tss@iki.fi>
parents:
14978
diff
changeset
|
64 unsigned int args_added_extra_eol:1; |
1023
dc660f588218
Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents:
1022
diff
changeset
|
65 unsigned int fatal_error:1; |
0 | 66 }; |
67 | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
68 struct imap_parser * |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
69 imap_parser_create(struct istream *input, struct ostream *output, |
1591
6eca99b727a0
IMAP parser memory limits are now enforced by bytes per line rather than
Timo Sirainen <tss@iki.fi>
parents:
1311
diff
changeset
|
70 size_t max_line_size) |
0 | 71 { |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
72 struct imap_parser *parser; |
0 | 73 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
74 parser = i_new(struct imap_parser, 1); |
13627
f63f2b2217c3
lib-imap: Added reference counting to imap parser.
Timo Sirainen <tss@iki.fi>
parents:
12860
diff
changeset
|
75 parser->refcount = 1; |
6739
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
76 parser->pool = pool_alloconly_create(MEMPOOL_GROWING"IMAP parser", |
15127
9f691edba099
Decrease minimum memory allocations.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
77 1024); |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
735
diff
changeset
|
78 parser->input = input; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
735
diff
changeset
|
79 parser->output = output; |
1591
6eca99b727a0
IMAP parser memory limits are now enforced by bytes per line rather than
Timo Sirainen <tss@iki.fi>
parents:
1311
diff
changeset
|
80 parser->max_line_size = max_line_size; |
444
85ab93a7693b
ImapArgList changed from linked list to array. easier to handle that way.
Timo Sirainen <tss@iki.fi>
parents:
424
diff
changeset
|
81 |
5836
9f869a7a3d73
Changed imap-parser API to use standard arrays for lists instead of its own
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
82 p_array_init(&parser->root_list, parser->pool, LIST_INIT_COUNT); |
9f869a7a3d73
Changed imap-parser API to use standard arrays for lists instead of its own
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
83 parser->cur_list = &parser->root_list; |
0 | 84 return parser; |
85 } | |
86 | |
13627
f63f2b2217c3
lib-imap: Added reference counting to imap parser.
Timo Sirainen <tss@iki.fi>
parents:
12860
diff
changeset
|
87 void imap_parser_ref(struct imap_parser *parser) |
0 | 88 { |
13627
f63f2b2217c3
lib-imap: Added reference counting to imap parser.
Timo Sirainen <tss@iki.fi>
parents:
12860
diff
changeset
|
89 i_assert(parser->refcount > 0); |
f63f2b2217c3
lib-imap: Added reference counting to imap parser.
Timo Sirainen <tss@iki.fi>
parents:
12860
diff
changeset
|
90 |
f63f2b2217c3
lib-imap: Added reference counting to imap parser.
Timo Sirainen <tss@iki.fi>
parents:
12860
diff
changeset
|
91 parser->refcount++; |
f63f2b2217c3
lib-imap: Added reference counting to imap parser.
Timo Sirainen <tss@iki.fi>
parents:
12860
diff
changeset
|
92 } |
f63f2b2217c3
lib-imap: Added reference counting to imap parser.
Timo Sirainen <tss@iki.fi>
parents:
12860
diff
changeset
|
93 |
22050
37e6375d1978
lib-imap: imap_parser_unref() should always set parser=NULL
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21390
diff
changeset
|
94 void imap_parser_unref(struct imap_parser **_parser) |
13627
f63f2b2217c3
lib-imap: Added reference counting to imap parser.
Timo Sirainen <tss@iki.fi>
parents:
12860
diff
changeset
|
95 { |
22050
37e6375d1978
lib-imap: imap_parser_unref() should always set parser=NULL
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21390
diff
changeset
|
96 struct imap_parser *parser = *_parser; |
13627
f63f2b2217c3
lib-imap: Added reference counting to imap parser.
Timo Sirainen <tss@iki.fi>
parents:
12860
diff
changeset
|
97 |
22050
37e6375d1978
lib-imap: imap_parser_unref() should always set parser=NULL
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21390
diff
changeset
|
98 *_parser = NULL; |
37e6375d1978
lib-imap: imap_parser_unref() should always set parser=NULL
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21390
diff
changeset
|
99 |
37e6375d1978
lib-imap: imap_parser_unref() should always set parser=NULL
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21390
diff
changeset
|
100 i_assert(parser->refcount > 0); |
37e6375d1978
lib-imap: imap_parser_unref() should always set parser=NULL
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21390
diff
changeset
|
101 if (--parser->refcount > 0) |
13627
f63f2b2217c3
lib-imap: Added reference counting to imap parser.
Timo Sirainen <tss@iki.fi>
parents:
12860
diff
changeset
|
102 return; |
f63f2b2217c3
lib-imap: Added reference counting to imap parser.
Timo Sirainen <tss@iki.fi>
parents:
12860
diff
changeset
|
103 |
22050
37e6375d1978
lib-imap: imap_parser_unref() should always set parser=NULL
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21390
diff
changeset
|
104 pool_unref(&parser->pool); |
37e6375d1978
lib-imap: imap_parser_unref() should always set parser=NULL
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21390
diff
changeset
|
105 i_free(parser); |
0 | 106 } |
107 | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
108 void imap_parser_reset(struct imap_parser *parser) |
0 | 109 { |
110 p_clear(parser->pool); | |
111 | |
1591
6eca99b727a0
IMAP parser memory limits are now enforced by bytes per line rather than
Timo Sirainen <tss@iki.fi>
parents:
1311
diff
changeset
|
112 parser->line_size = 0; |
6eca99b727a0
IMAP parser memory limits are now enforced by bytes per line rather than
Timo Sirainen <tss@iki.fi>
parents:
1311
diff
changeset
|
113 |
5836
9f869a7a3d73
Changed imap-parser API to use standard arrays for lists instead of its own
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
114 p_array_init(&parser->root_list, parser->pool, LIST_INIT_COUNT); |
9f869a7a3d73
Changed imap-parser API to use standard arrays for lists instead of its own
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
115 parser->cur_list = &parser->root_list; |
444
85ab93a7693b
ImapArgList changed from linked list to array. easier to handle that way.
Timo Sirainen <tss@iki.fi>
parents:
424
diff
changeset
|
116 parser->list_arg = NULL; |
0 | 117 |
118 parser->cur_type = ARG_PARSE_NONE; | |
119 parser->cur_pos = 0; | |
15129
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
120 parser->cur_resp_text = FALSE; |
0 | 121 |
444
85ab93a7693b
ImapArgList changed from linked list to array. easier to handle that way.
Timo Sirainen <tss@iki.fi>
parents:
424
diff
changeset
|
122 parser->str_first_escape = 0; |
85ab93a7693b
ImapArgList changed from linked list to array. easier to handle that way.
Timo Sirainen <tss@iki.fi>
parents:
424
diff
changeset
|
123 parser->literal_size = 0; |
0 | 124 |
768
8b3518bb327e
Limited max. command argument elements to 128. Added more verbose error
Timo Sirainen <tss@iki.fi>
parents:
764
diff
changeset
|
125 parser->error = NULL; |
8b3518bb327e
Limited max. command argument elements to 128. Added more verbose error
Timo Sirainen <tss@iki.fi>
parents:
764
diff
changeset
|
126 |
444
85ab93a7693b
ImapArgList changed from linked list to array. easier to handle that way.
Timo Sirainen <tss@iki.fi>
parents:
424
diff
changeset
|
127 parser->literal_skip_crlf = FALSE; |
0 | 128 parser->eol = FALSE; |
14979
e0a3812771fd
imap-parser: Allow calling imap_parser_read_args() multiple times with larger count parameter.
Timo Sirainen <tss@iki.fi>
parents:
14978
diff
changeset
|
129 parser->args_added_extra_eol = FALSE; |
6739
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
130 parser->literal_size_return = FALSE; |
0 | 131 } |
132 | |
10697
e0e6d941941c
lib-imap: Added imap_parser_set_streams().
Timo Sirainen <tss@iki.fi>
parents:
10582
diff
changeset
|
133 void imap_parser_set_streams(struct imap_parser *parser, struct istream *input, |
e0e6d941941c
lib-imap: Added imap_parser_set_streams().
Timo Sirainen <tss@iki.fi>
parents:
10582
diff
changeset
|
134 struct ostream *output) |
e0e6d941941c
lib-imap: Added imap_parser_set_streams().
Timo Sirainen <tss@iki.fi>
parents:
10582
diff
changeset
|
135 { |
e0e6d941941c
lib-imap: Added imap_parser_set_streams().
Timo Sirainen <tss@iki.fi>
parents:
10582
diff
changeset
|
136 parser->input = input; |
e0e6d941941c
lib-imap: Added imap_parser_set_streams().
Timo Sirainen <tss@iki.fi>
parents:
10582
diff
changeset
|
137 parser->output = output; |
e0e6d941941c
lib-imap: Added imap_parser_set_streams().
Timo Sirainen <tss@iki.fi>
parents:
10582
diff
changeset
|
138 } |
e0e6d941941c
lib-imap: Added imap_parser_set_streams().
Timo Sirainen <tss@iki.fi>
parents:
10582
diff
changeset
|
139 |
3863
55df57c028d4
Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents:
3481
diff
changeset
|
140 const char *imap_parser_get_error(struct imap_parser *parser, bool *fatal) |
768
8b3518bb327e
Limited max. command argument elements to 128. Added more verbose error
Timo Sirainen <tss@iki.fi>
parents:
764
diff
changeset
|
141 { |
1023
dc660f588218
Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents:
1022
diff
changeset
|
142 *fatal = parser->fatal_error; |
768
8b3518bb327e
Limited max. command argument elements to 128. Added more verbose error
Timo Sirainen <tss@iki.fi>
parents:
764
diff
changeset
|
143 return parser->error; |
8b3518bb327e
Limited max. command argument elements to 128. Added more verbose error
Timo Sirainen <tss@iki.fi>
parents:
764
diff
changeset
|
144 } |
8b3518bb327e
Limited max. command argument elements to 128. Added more verbose error
Timo Sirainen <tss@iki.fi>
parents:
764
diff
changeset
|
145 |
502
7927650f3b9b
imap_parser_read_args() didn't correctly always return "need for more data"
Timo Sirainen <tss@iki.fi>
parents:
469
diff
changeset
|
146 /* skip over everything parsed so far, plus the following whitespace */ |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
147 static int imap_parser_skip_to_next(struct imap_parser *parser, |
898
0d5be52d7131
Use unsigned char* when accessing non-NUL terminating strings. Compiler
Timo Sirainen <tss@iki.fi>
parents:
896
diff
changeset
|
148 const unsigned char **data, |
502
7927650f3b9b
imap_parser_read_args() didn't correctly always return "need for more data"
Timo Sirainen <tss@iki.fi>
parents:
469
diff
changeset
|
149 size_t *data_size) |
0 | 150 { |
184 | 151 size_t i; |
0 | 152 |
153 for (i = parser->cur_pos; i < *data_size; i++) { | |
154 if ((*data)[i] != ' ') | |
155 break; | |
156 } | |
157 | |
1591
6eca99b727a0
IMAP parser memory limits are now enforced by bytes per line rather than
Timo Sirainen <tss@iki.fi>
parents:
1311
diff
changeset
|
158 parser->line_size += i; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
735
diff
changeset
|
159 i_stream_skip(parser->input, i); |
0 | 160 parser->cur_pos = 0; |
161 | |
162 *data += i; | |
163 *data_size -= i; | |
164 return *data_size > 0; | |
165 } | |
166 | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
167 static struct imap_arg *imap_arg_create(struct imap_parser *parser) |
0 | 168 { |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
169 struct imap_arg *arg; |
0 | 170 |
5836
9f869a7a3d73
Changed imap-parser API to use standard arrays for lists instead of its own
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
171 arg = array_append_space(parser->cur_list); |
444
85ab93a7693b
ImapArgList changed from linked list to array. easier to handle that way.
Timo Sirainen <tss@iki.fi>
parents:
424
diff
changeset
|
172 arg->parent = parser->list_arg; |
85ab93a7693b
ImapArgList changed from linked list to array. easier to handle that way.
Timo Sirainen <tss@iki.fi>
parents:
424
diff
changeset
|
173 return arg; |
0 | 174 } |
175 | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
176 static void imap_parser_open_list(struct imap_parser *parser) |
0 | 177 { |
444
85ab93a7693b
ImapArgList changed from linked list to array. easier to handle that way.
Timo Sirainen <tss@iki.fi>
parents:
424
diff
changeset
|
178 parser->list_arg = imap_arg_create(parser); |
85ab93a7693b
ImapArgList changed from linked list to array. easier to handle that way.
Timo Sirainen <tss@iki.fi>
parents:
424
diff
changeset
|
179 parser->list_arg->type = IMAP_ARG_LIST; |
5836
9f869a7a3d73
Changed imap-parser API to use standard arrays for lists instead of its own
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
180 p_array_init(&parser->list_arg->_data.list, parser->pool, |
9f869a7a3d73
Changed imap-parser API to use standard arrays for lists instead of its own
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
181 LIST_INIT_COUNT); |
9f869a7a3d73
Changed imap-parser API to use standard arrays for lists instead of its own
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
182 parser->cur_list = &parser->list_arg->_data.list; |
0 | 183 |
184 parser->cur_type = ARG_PARSE_NONE; | |
185 } | |
186 | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
187 static int imap_parser_close_list(struct imap_parser *parser) |
0 | 188 { |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
189 struct imap_arg *arg; |
0 | 190 |
444
85ab93a7693b
ImapArgList changed from linked list to array. easier to handle that way.
Timo Sirainen <tss@iki.fi>
parents:
424
diff
changeset
|
191 if (parser->list_arg == NULL) { |
0 | 192 /* we're not inside list */ |
14589
c54dd35e1c0e
imap-parser: Added IMAP_PARSE_FLAG_INSIDE_LIST flag.
Stephan Bosch <stephan@rename-it.nl>
parents:
14133
diff
changeset
|
193 if ((parser->flags & IMAP_PARSE_FLAG_INSIDE_LIST) != 0) { |
c54dd35e1c0e
imap-parser: Added IMAP_PARSE_FLAG_INSIDE_LIST flag.
Stephan Bosch <stephan@rename-it.nl>
parents:
14133
diff
changeset
|
194 parser->eol = TRUE; |
c54dd35e1c0e
imap-parser: Added IMAP_PARSE_FLAG_INSIDE_LIST flag.
Stephan Bosch <stephan@rename-it.nl>
parents:
14133
diff
changeset
|
195 parser->cur_type = ARG_PARSE_NONE; |
c54dd35e1c0e
imap-parser: Added IMAP_PARSE_FLAG_INSIDE_LIST flag.
Stephan Bosch <stephan@rename-it.nl>
parents:
14133
diff
changeset
|
196 return TRUE; |
c54dd35e1c0e
imap-parser: Added IMAP_PARSE_FLAG_INSIDE_LIST flag.
Stephan Bosch <stephan@rename-it.nl>
parents:
14133
diff
changeset
|
197 } |
768
8b3518bb327e
Limited max. command argument elements to 128. Added more verbose error
Timo Sirainen <tss@iki.fi>
parents:
764
diff
changeset
|
198 parser->error = "Unexpected ')'"; |
0 | 199 return FALSE; |
200 } | |
201 | |
444
85ab93a7693b
ImapArgList changed from linked list to array. easier to handle that way.
Timo Sirainen <tss@iki.fi>
parents:
424
diff
changeset
|
202 arg = imap_arg_create(parser); |
85ab93a7693b
ImapArgList changed from linked list to array. easier to handle that way.
Timo Sirainen <tss@iki.fi>
parents:
424
diff
changeset
|
203 arg->type = IMAP_ARG_EOL; |
85ab93a7693b
ImapArgList changed from linked list to array. easier to handle that way.
Timo Sirainen <tss@iki.fi>
parents:
424
diff
changeset
|
204 |
85ab93a7693b
ImapArgList changed from linked list to array. easier to handle that way.
Timo Sirainen <tss@iki.fi>
parents:
424
diff
changeset
|
205 parser->list_arg = parser->list_arg->parent; |
85ab93a7693b
ImapArgList changed from linked list to array. easier to handle that way.
Timo Sirainen <tss@iki.fi>
parents:
424
diff
changeset
|
206 if (parser->list_arg == NULL) { |
5836
9f869a7a3d73
Changed imap-parser API to use standard arrays for lists instead of its own
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
207 parser->cur_list = &parser->root_list; |
444
85ab93a7693b
ImapArgList changed from linked list to array. easier to handle that way.
Timo Sirainen <tss@iki.fi>
parents:
424
diff
changeset
|
208 } else { |
5836
9f869a7a3d73
Changed imap-parser API to use standard arrays for lists instead of its own
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
209 parser->cur_list = &parser->list_arg->_data.list; |
0 | 210 } |
211 | |
212 parser->cur_type = ARG_PARSE_NONE; | |
213 return TRUE; | |
214 } | |
215 | |
12614
1e88287fc721
lib-imap: struct imap_arg.str_size now contains the string value lengths.
Timo Sirainen <tss@iki.fi>
parents:
11345
diff
changeset
|
216 static char * |
1e88287fc721
lib-imap: struct imap_arg.str_size now contains the string value lengths.
Timo Sirainen <tss@iki.fi>
parents:
11345
diff
changeset
|
217 imap_parser_strdup(struct imap_parser *parser, |
1e88287fc721
lib-imap: struct imap_arg.str_size now contains the string value lengths.
Timo Sirainen <tss@iki.fi>
parents:
11345
diff
changeset
|
218 const void *data, size_t len) |
1e88287fc721
lib-imap: struct imap_arg.str_size now contains the string value lengths.
Timo Sirainen <tss@iki.fi>
parents:
11345
diff
changeset
|
219 { |
1e88287fc721
lib-imap: struct imap_arg.str_size now contains the string value lengths.
Timo Sirainen <tss@iki.fi>
parents:
11345
diff
changeset
|
220 char *ret; |
1e88287fc721
lib-imap: struct imap_arg.str_size now contains the string value lengths.
Timo Sirainen <tss@iki.fi>
parents:
11345
diff
changeset
|
221 |
1e88287fc721
lib-imap: struct imap_arg.str_size now contains the string value lengths.
Timo Sirainen <tss@iki.fi>
parents:
11345
diff
changeset
|
222 ret = p_malloc(parser->pool, len + 1); |
1e88287fc721
lib-imap: struct imap_arg.str_size now contains the string value lengths.
Timo Sirainen <tss@iki.fi>
parents:
11345
diff
changeset
|
223 memcpy(ret, data, len); |
1e88287fc721
lib-imap: struct imap_arg.str_size now contains the string value lengths.
Timo Sirainen <tss@iki.fi>
parents:
11345
diff
changeset
|
224 return ret; |
1e88287fc721
lib-imap: struct imap_arg.str_size now contains the string value lengths.
Timo Sirainen <tss@iki.fi>
parents:
11345
diff
changeset
|
225 } |
1e88287fc721
lib-imap: struct imap_arg.str_size now contains the string value lengths.
Timo Sirainen <tss@iki.fi>
parents:
11345
diff
changeset
|
226 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
227 static void imap_parser_save_arg(struct imap_parser *parser, |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
228 const unsigned char *data, size_t size) |
0 | 229 { |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
230 struct imap_arg *arg; |
5835
d59ed6a31b66
Added more consts to imap-parser API
Timo Sirainen <tss@iki.fi>
parents:
5024
diff
changeset
|
231 char *str; |
0 | 232 |
444
85ab93a7693b
ImapArgList changed from linked list to array. easier to handle that way.
Timo Sirainen <tss@iki.fi>
parents:
424
diff
changeset
|
233 arg = imap_arg_create(parser); |
0 | 234 |
235 switch (parser->cur_type) { | |
236 case ARG_PARSE_ATOM: | |
15129
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
237 case ARG_PARSE_TEXT: |
16914
09d5728a69d1
lib-imap: IMAP protocol parser was parsing NIL case-sensitively.
Timo Sirainen <tss@iki.fi>
parents:
16520
diff
changeset
|
238 if (size == 3 && i_memcasecmp(data, "NIL", 3) == 0) { |
16920
1d7e2cee2c4b
lib-imap: Fixed NIL astring to not lose its case-sensitivity.
Timo Sirainen <tss@iki.fi>
parents:
16915
diff
changeset
|
239 /* NIL argument. it might be an actual NIL, but if |
1d7e2cee2c4b
lib-imap: Fixed NIL astring to not lose its case-sensitivity.
Timo Sirainen <tss@iki.fi>
parents:
16915
diff
changeset
|
240 we're reading astring, it's an atom and we can't |
1d7e2cee2c4b
lib-imap: Fixed NIL astring to not lose its case-sensitivity.
Timo Sirainen <tss@iki.fi>
parents:
16915
diff
changeset
|
241 lose its case. */ |
0 | 242 arg->type = IMAP_ARG_NIL; |
243 } else { | |
244 /* simply save the string */ | |
245 arg->type = IMAP_ARG_ATOM; | |
246 } | |
16920
1d7e2cee2c4b
lib-imap: Fixed NIL astring to not lose its case-sensitivity.
Timo Sirainen <tss@iki.fi>
parents:
16915
diff
changeset
|
247 arg->_data.str = imap_parser_strdup(parser, data, size); |
1d7e2cee2c4b
lib-imap: Fixed NIL astring to not lose its case-sensitivity.
Timo Sirainen <tss@iki.fi>
parents:
16915
diff
changeset
|
248 arg->str_len = size; |
0 | 249 break; |
250 case ARG_PARSE_STRING: | |
251 /* data is quoted and may contain escapes. */ | |
898
0d5be52d7131
Use unsigned char* when accessing non-NUL terminating strings. Compiler
Timo Sirainen <tss@iki.fi>
parents:
896
diff
changeset
|
252 i_assert(size > 0); |
444
85ab93a7693b
ImapArgList changed from linked list to array. easier to handle that way.
Timo Sirainen <tss@iki.fi>
parents:
424
diff
changeset
|
253 |
0 | 254 arg->type = IMAP_ARG_STRING; |
5835
d59ed6a31b66
Added more consts to imap-parser API
Timo Sirainen <tss@iki.fi>
parents:
5024
diff
changeset
|
255 str = p_strndup(parser->pool, data+1, size-1); |
0 | 256 |
257 /* remove the escapes */ | |
444
85ab93a7693b
ImapArgList changed from linked list to array. easier to handle that way.
Timo Sirainen <tss@iki.fi>
parents:
424
diff
changeset
|
258 if (parser->str_first_escape >= 0 && |
85ab93a7693b
ImapArgList changed from linked list to array. easier to handle that way.
Timo Sirainen <tss@iki.fi>
parents:
424
diff
changeset
|
259 (parser->flags & IMAP_PARSE_FLAG_NO_UNESCAPE) == 0) { |
0 | 260 /* -1 because we skipped the '"' prefix */ |
14682
d0d7b810646b
Make sure we check all the functions' return values. Minor API changes to simplify this.
Timo Sirainen <tss@iki.fi>
parents:
14681
diff
changeset
|
261 (void)str_unescape(str + parser->str_first_escape-1); |
0 | 262 } |
5835
d59ed6a31b66
Added more consts to imap-parser API
Timo Sirainen <tss@iki.fi>
parents:
5024
diff
changeset
|
263 arg->_data.str = str; |
12614
1e88287fc721
lib-imap: struct imap_arg.str_size now contains the string value lengths.
Timo Sirainen <tss@iki.fi>
parents:
11345
diff
changeset
|
264 arg->str_len = strlen(str); |
0 | 265 break; |
266 case ARG_PARSE_LITERAL_DATA: | |
1107
4044c2903ed7
Don't do x-unknown mime encoding. Correct way is to just send them as
Timo Sirainen <tss@iki.fi>
parents:
1068
diff
changeset
|
267 if ((parser->flags & IMAP_PARSE_FLAG_LITERAL_SIZE) != 0) { |
0 | 268 /* save literal size */ |
1022
09bac2875ed8
Support for LITERAL+ extension.
Timo Sirainen <tss@iki.fi>
parents:
1014
diff
changeset
|
269 arg->type = parser->literal_nonsync ? |
09bac2875ed8
Support for LITERAL+ extension.
Timo Sirainen <tss@iki.fi>
parents:
1014
diff
changeset
|
270 IMAP_ARG_LITERAL_SIZE_NONSYNC : |
09bac2875ed8
Support for LITERAL+ extension.
Timo Sirainen <tss@iki.fi>
parents:
1014
diff
changeset
|
271 IMAP_ARG_LITERAL_SIZE; |
877
7935347f54f1
Don't access ImapArg's union members directly - too easy to mess up. Fixes a
Timo Sirainen <tss@iki.fi>
parents:
825
diff
changeset
|
272 arg->_data.literal_size = parser->literal_size; |
14607
68a8b650578e
imap parser: Added support for parsing literal8 (for BINARY extension)
Timo Sirainen <tss@iki.fi>
parents:
14589
diff
changeset
|
273 arg->literal8 = parser->literal8; |
6739
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
274 break; |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
275 } |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
276 /* fall through */ |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
277 case ARG_PARSE_LITERAL_DATA_FORCED: |
12614
1e88287fc721
lib-imap: struct imap_arg.str_size now contains the string value lengths.
Timo Sirainen <tss@iki.fi>
parents:
11345
diff
changeset
|
278 if ((parser->flags & IMAP_PARSE_FLAG_LITERAL_TYPE) != 0) |
1107
4044c2903ed7
Don't do x-unknown mime encoding. Correct way is to just send them as
Timo Sirainen <tss@iki.fi>
parents:
1068
diff
changeset
|
279 arg->type = IMAP_ARG_LITERAL; |
12614
1e88287fc721
lib-imap: struct imap_arg.str_size now contains the string value lengths.
Timo Sirainen <tss@iki.fi>
parents:
11345
diff
changeset
|
280 else |
1107
4044c2903ed7
Don't do x-unknown mime encoding. Correct way is to just send them as
Timo Sirainen <tss@iki.fi>
parents:
1068
diff
changeset
|
281 arg->type = IMAP_ARG_STRING; |
12614
1e88287fc721
lib-imap: struct imap_arg.str_size now contains the string value lengths.
Timo Sirainen <tss@iki.fi>
parents:
11345
diff
changeset
|
282 arg->_data.str = imap_parser_strdup(parser, data, size); |
14607
68a8b650578e
imap parser: Added support for parsing literal8 (for BINARY extension)
Timo Sirainen <tss@iki.fi>
parents:
14589
diff
changeset
|
283 arg->literal8 = parser->literal8; |
12614
1e88287fc721
lib-imap: struct imap_arg.str_size now contains the string value lengths.
Timo Sirainen <tss@iki.fi>
parents:
11345
diff
changeset
|
284 arg->str_len = size; |
0 | 285 break; |
286 default: | |
546
e1254b838e0b
Added --enable-asserts (default) and fixed some warnings when building
Timo Sirainen <tss@iki.fi>
parents:
504
diff
changeset
|
287 i_unreached(); |
0 | 288 } |
289 | |
502
7927650f3b9b
imap_parser_read_args() didn't correctly always return "need for more data"
Timo Sirainen <tss@iki.fi>
parents:
469
diff
changeset
|
290 parser->cur_type = ARG_PARSE_NONE; |
0 | 291 } |
292 | |
1169
0eaf51e01ccd
Allow wildcards anyway in atoms, they're needed with LIST.
Timo Sirainen <tss@iki.fi>
parents:
1167
diff
changeset
|
293 static int is_valid_atom_char(struct imap_parser *parser, char chr) |
0eaf51e01ccd
Allow wildcards anyway in atoms, they're needed with LIST.
Timo Sirainen <tss@iki.fi>
parents:
1167
diff
changeset
|
294 { |
6889
3ec5a07d00f2
Added IMAP_PARSE_FLAG_ATOM_ALLCHARS.
Timo Sirainen <tss@iki.fi>
parents:
6739
diff
changeset
|
295 const char *error; |
3ec5a07d00f2
Added IMAP_PARSE_FLAG_ATOM_ALLCHARS.
Timo Sirainen <tss@iki.fi>
parents:
6739
diff
changeset
|
296 |
15245
42f99a4fc763
lib-imap: Changed public IS_ATOM*() macros to match RFC 3501 exactly.
Timo Sirainen <tss@iki.fi>
parents:
15162
diff
changeset
|
297 if (IS_ATOM_PARSER_INPUT((unsigned char)chr)) |
6889
3ec5a07d00f2
Added IMAP_PARSE_FLAG_ATOM_ALLCHARS.
Timo Sirainen <tss@iki.fi>
parents:
6739
diff
changeset
|
298 error = "Invalid characters in atom"; |
6946
49ba86f65da5
Fixed handling invalid characters in atoms.
Timo Sirainen <tss@iki.fi>
parents:
6889
diff
changeset
|
299 else if ((chr & 0x80) != 0) |
6889
3ec5a07d00f2
Added IMAP_PARSE_FLAG_ATOM_ALLCHARS.
Timo Sirainen <tss@iki.fi>
parents:
6739
diff
changeset
|
300 error = "8bit data in atom"; |
6946
49ba86f65da5
Fixed handling invalid characters in atoms.
Timo Sirainen <tss@iki.fi>
parents:
6889
diff
changeset
|
301 else |
6889
3ec5a07d00f2
Added IMAP_PARSE_FLAG_ATOM_ALLCHARS.
Timo Sirainen <tss@iki.fi>
parents:
6739
diff
changeset
|
302 return TRUE; |
1169
0eaf51e01ccd
Allow wildcards anyway in atoms, they're needed with LIST.
Timo Sirainen <tss@iki.fi>
parents:
1167
diff
changeset
|
303 |
6889
3ec5a07d00f2
Added IMAP_PARSE_FLAG_ATOM_ALLCHARS.
Timo Sirainen <tss@iki.fi>
parents:
6739
diff
changeset
|
304 if ((parser->flags & IMAP_PARSE_FLAG_ATOM_ALLCHARS) != 0) |
3ec5a07d00f2
Added IMAP_PARSE_FLAG_ATOM_ALLCHARS.
Timo Sirainen <tss@iki.fi>
parents:
6739
diff
changeset
|
305 return TRUE; |
3ec5a07d00f2
Added IMAP_PARSE_FLAG_ATOM_ALLCHARS.
Timo Sirainen <tss@iki.fi>
parents:
6739
diff
changeset
|
306 parser->error = error; |
3ec5a07d00f2
Added IMAP_PARSE_FLAG_ATOM_ALLCHARS.
Timo Sirainen <tss@iki.fi>
parents:
6739
diff
changeset
|
307 return FALSE; |
1169
0eaf51e01ccd
Allow wildcards anyway in atoms, they're needed with LIST.
Timo Sirainen <tss@iki.fi>
parents:
1167
diff
changeset
|
308 } |
0eaf51e01ccd
Allow wildcards anyway in atoms, they're needed with LIST.
Timo Sirainen <tss@iki.fi>
parents:
1167
diff
changeset
|
309 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
310 static int imap_parser_read_atom(struct imap_parser *parser, |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
311 const unsigned char *data, size_t data_size) |
0 | 312 { |
184 | 313 size_t i; |
0 | 314 |
2675
60d33cf81c8e
BODY.PEEK[HEADER.FIELDS (...)] list is allowed to contain strings and
Timo Sirainen <tss@iki.fi>
parents:
1661
diff
changeset
|
315 /* read until we've found space, CR or LF. */ |
0 | 316 for (i = parser->cur_pos; i < data_size; i++) { |
7131
0355a4603e80
If IMAP_PARSE_FLAG_ATOM_ALLCHARS is enabled, allow also ')' characters in
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
317 if (data[i] == ' ' || is_linebreak(data[i])) { |
2675
60d33cf81c8e
BODY.PEEK[HEADER.FIELDS (...)] list is allowed to contain strings and
Timo Sirainen <tss@iki.fi>
parents:
1661
diff
changeset
|
318 imap_parser_save_arg(parser, data, i); |
60d33cf81c8e
BODY.PEEK[HEADER.FIELDS (...)] list is allowed to contain strings and
Timo Sirainen <tss@iki.fi>
parents:
1661
diff
changeset
|
319 break; |
7131
0355a4603e80
If IMAP_PARSE_FLAG_ATOM_ALLCHARS is enabled, allow also ')' characters in
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
320 } else if (data[i] == ')') { |
14589
c54dd35e1c0e
imap-parser: Added IMAP_PARSE_FLAG_INSIDE_LIST flag.
Stephan Bosch <stephan@rename-it.nl>
parents:
14133
diff
changeset
|
321 if (parser->list_arg != NULL || |
c54dd35e1c0e
imap-parser: Added IMAP_PARSE_FLAG_INSIDE_LIST flag.
Stephan Bosch <stephan@rename-it.nl>
parents:
14133
diff
changeset
|
322 (parser->flags & IMAP_PARSE_FLAG_INSIDE_LIST) != 0) { |
7131
0355a4603e80
If IMAP_PARSE_FLAG_ATOM_ALLCHARS is enabled, allow also ')' characters in
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
323 imap_parser_save_arg(parser, data, i); |
0355a4603e80
If IMAP_PARSE_FLAG_ATOM_ALLCHARS is enabled, allow also ')' characters in
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
324 break; |
11345
01f81b9e9586
imap parser: Fail immediately if we see unexpected ')' while reading atom.
Timo Sirainen <tss@iki.fi>
parents:
11063
diff
changeset
|
325 } else if ((parser->flags & |
01f81b9e9586
imap parser: Fail immediately if we see unexpected ')' while reading atom.
Timo Sirainen <tss@iki.fi>
parents:
11063
diff
changeset
|
326 IMAP_PARSE_FLAG_ATOM_ALLCHARS) == 0) { |
01f81b9e9586
imap parser: Fail immediately if we see unexpected ')' while reading atom.
Timo Sirainen <tss@iki.fi>
parents:
11063
diff
changeset
|
327 parser->error = "Unexpected ')'"; |
01f81b9e9586
imap parser: Fail immediately if we see unexpected ')' while reading atom.
Timo Sirainen <tss@iki.fi>
parents:
11063
diff
changeset
|
328 return FALSE; |
7131
0355a4603e80
If IMAP_PARSE_FLAG_ATOM_ALLCHARS is enabled, allow also ')' characters in
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
329 } |
0355a4603e80
If IMAP_PARSE_FLAG_ATOM_ALLCHARS is enabled, allow also ')' characters in
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
330 /* assume it's part of the atom */ |
2675
60d33cf81c8e
BODY.PEEK[HEADER.FIELDS (...)] list is allowed to contain strings and
Timo Sirainen <tss@iki.fi>
parents:
1661
diff
changeset
|
331 } else if (!is_valid_atom_char(parser, data[i])) |
60d33cf81c8e
BODY.PEEK[HEADER.FIELDS (...)] list is allowed to contain strings and
Timo Sirainen <tss@iki.fi>
parents:
1661
diff
changeset
|
332 return FALSE; |
0 | 333 } |
334 | |
335 parser->cur_pos = i; | |
717
3f817df5eba4
Input parsing was a bit broken in some conditions. Mostly visible with
Timo Sirainen <tss@iki.fi>
parents:
546
diff
changeset
|
336 return parser->cur_type == ARG_PARSE_NONE; |
0 | 337 } |
338 | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
339 static int imap_parser_read_string(struct imap_parser *parser, |
898
0d5be52d7131
Use unsigned char* when accessing non-NUL terminating strings. Compiler
Timo Sirainen <tss@iki.fi>
parents:
896
diff
changeset
|
340 const unsigned char *data, size_t data_size) |
0 | 341 { |
184 | 342 size_t i; |
0 | 343 |
344 /* read until we've found non-escaped ", CR or LF */ | |
345 for (i = parser->cur_pos; i < data_size; i++) { | |
346 if (data[i] == '"') { | |
347 imap_parser_save_arg(parser, data, i); | |
348 | |
349 i++; /* skip the trailing '"' too */ | |
350 break; | |
351 } | |
352 | |
353 if (data[i] == '\\') { | |
354 if (i+1 == data_size) { | |
355 /* known data ends with '\' - leave it to | |
356 next time as well if it happens to be \" */ | |
357 break; | |
358 } | |
359 | |
360 /* save the first escaped char */ | |
361 if (parser->str_first_escape < 0) | |
362 parser->str_first_escape = i; | |
363 | |
364 /* skip the escaped char */ | |
365 i++; | |
366 } | |
367 | |
368 /* check linebreaks here, so escaping CR/LF isn't possible. | |
369 string always ends with '"', so it's an error if we found | |
370 a linebreak.. */ | |
8837
c9d6ae6f10fe
imap-parser: Added IMAP_PARSE_FLAG_MULTILINE_STR flag.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
371 if (is_linebreak(data[i]) && |
c9d6ae6f10fe
imap-parser: Added IMAP_PARSE_FLAG_MULTILINE_STR flag.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
372 (parser->flags & IMAP_PARSE_FLAG_MULTILINE_STR) == 0) { |
768
8b3518bb327e
Limited max. command argument elements to 128. Added more verbose error
Timo Sirainen <tss@iki.fi>
parents:
764
diff
changeset
|
373 parser->error = "Missing '\"'"; |
0 | 374 return FALSE; |
375 } | |
376 } | |
377 | |
378 parser->cur_pos = i; | |
717
3f817df5eba4
Input parsing was a bit broken in some conditions. Mostly visible with
Timo Sirainen <tss@iki.fi>
parents:
546
diff
changeset
|
379 return parser->cur_type == ARG_PARSE_NONE; |
0 | 380 } |
381 | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
382 static int imap_parser_literal_end(struct imap_parser *parser) |
308
899d3e189dbf
We didn't allow saving messages longer than 8192 bytes. Now we also send the
Timo Sirainen <tss@iki.fi>
parents:
184
diff
changeset
|
383 { |
1288
fa47d787c2aa
Literal parser broke if \r\n wasn't in buffer at the time '}' was parsed.
Timo Sirainen <tss@iki.fi>
parents:
1175
diff
changeset
|
384 if ((parser->flags & IMAP_PARSE_FLAG_LITERAL_SIZE) == 0) { |
1591
6eca99b727a0
IMAP parser memory limits are now enforced by bytes per line rather than
Timo Sirainen <tss@iki.fi>
parents:
1311
diff
changeset
|
385 if (parser->line_size >= parser->max_line_size || |
6eca99b727a0
IMAP parser memory limits are now enforced by bytes per line rather than
Timo Sirainen <tss@iki.fi>
parents:
1311
diff
changeset
|
386 parser->literal_size > |
6eca99b727a0
IMAP parser memory limits are now enforced by bytes per line rather than
Timo Sirainen <tss@iki.fi>
parents:
1311
diff
changeset
|
387 parser->max_line_size - parser->line_size) { |
308
899d3e189dbf
We didn't allow saving messages longer than 8192 bytes. Now we also send the
Timo Sirainen <tss@iki.fi>
parents:
184
diff
changeset
|
388 /* too long string, abort. */ |
768
8b3518bb327e
Limited max. command argument elements to 128. Added more verbose error
Timo Sirainen <tss@iki.fi>
parents:
764
diff
changeset
|
389 parser->error = "Literal size too large"; |
1023
dc660f588218
Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents:
1022
diff
changeset
|
390 parser->fatal_error = TRUE; |
308
899d3e189dbf
We didn't allow saving messages longer than 8192 bytes. Now we also send the
Timo Sirainen <tss@iki.fi>
parents:
184
diff
changeset
|
391 return FALSE; |
899d3e189dbf
We didn't allow saving messages longer than 8192 bytes. Now we also send the
Timo Sirainen <tss@iki.fi>
parents:
184
diff
changeset
|
392 } |
899d3e189dbf
We didn't allow saving messages longer than 8192 bytes. Now we also send the
Timo Sirainen <tss@iki.fi>
parents:
184
diff
changeset
|
393 |
1022
09bac2875ed8
Support for LITERAL+ extension.
Timo Sirainen <tss@iki.fi>
parents:
1014
diff
changeset
|
394 if (parser->output != NULL && !parser->literal_nonsync) { |
14681
ca37d1577291
Added o_stream_nsend*() and related functions to make delayed error handling safer.
Timo Sirainen <tss@iki.fi>
parents:
14629
diff
changeset
|
395 o_stream_nsend(parser->output, "+ OK\r\n", 6); |
ca37d1577291
Added o_stream_nsend*() and related functions to make delayed error handling safer.
Timo Sirainen <tss@iki.fi>
parents:
14629
diff
changeset
|
396 o_stream_nflush(parser->output); |
408
e057845d94ca
Dropped sent_time and alignment from MailIndexRecord. SEARCH can now use
Timo Sirainen <tss@iki.fi>
parents:
348
diff
changeset
|
397 } |
308
899d3e189dbf
We didn't allow saving messages longer than 8192 bytes. Now we also send the
Timo Sirainen <tss@iki.fi>
parents:
184
diff
changeset
|
398 } |
899d3e189dbf
We didn't allow saving messages longer than 8192 bytes. Now we also send the
Timo Sirainen <tss@iki.fi>
parents:
184
diff
changeset
|
399 |
899d3e189dbf
We didn't allow saving messages longer than 8192 bytes. Now we also send the
Timo Sirainen <tss@iki.fi>
parents:
184
diff
changeset
|
400 parser->cur_type = ARG_PARSE_LITERAL_DATA; |
899d3e189dbf
We didn't allow saving messages longer than 8192 bytes. Now we also send the
Timo Sirainen <tss@iki.fi>
parents:
184
diff
changeset
|
401 parser->literal_skip_crlf = TRUE; |
899d3e189dbf
We didn't allow saving messages longer than 8192 bytes. Now we also send the
Timo Sirainen <tss@iki.fi>
parents:
184
diff
changeset
|
402 |
899d3e189dbf
We didn't allow saving messages longer than 8192 bytes. Now we also send the
Timo Sirainen <tss@iki.fi>
parents:
184
diff
changeset
|
403 parser->cur_pos = 0; |
899d3e189dbf
We didn't allow saving messages longer than 8192 bytes. Now we also send the
Timo Sirainen <tss@iki.fi>
parents:
184
diff
changeset
|
404 return TRUE; |
899d3e189dbf
We didn't allow saving messages longer than 8192 bytes. Now we also send the
Timo Sirainen <tss@iki.fi>
parents:
184
diff
changeset
|
405 } |
899d3e189dbf
We didn't allow saving messages longer than 8192 bytes. Now we also send the
Timo Sirainen <tss@iki.fi>
parents:
184
diff
changeset
|
406 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
407 static int imap_parser_read_literal(struct imap_parser *parser, |
898
0d5be52d7131
Use unsigned char* when accessing non-NUL terminating strings. Compiler
Timo Sirainen <tss@iki.fi>
parents:
896
diff
changeset
|
408 const unsigned char *data, |
184 | 409 size_t data_size) |
0 | 410 { |
184 | 411 size_t i, prev_size; |
0 | 412 |
413 /* expecting digits + "}" */ | |
414 for (i = parser->cur_pos; i < data_size; i++) { | |
415 if (data[i] == '}') { | |
1591
6eca99b727a0
IMAP parser memory limits are now enforced by bytes per line rather than
Timo Sirainen <tss@iki.fi>
parents:
1311
diff
changeset
|
416 parser->line_size += i+1; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
735
diff
changeset
|
417 i_stream_skip(parser->input, i+1); |
717
3f817df5eba4
Input parsing was a bit broken in some conditions. Mostly visible with
Timo Sirainen <tss@iki.fi>
parents:
546
diff
changeset
|
418 return imap_parser_literal_end(parser); |
0 | 419 } |
420 | |
1022
09bac2875ed8
Support for LITERAL+ extension.
Timo Sirainen <tss@iki.fi>
parents:
1014
diff
changeset
|
421 if (parser->literal_nonsync) { |
09bac2875ed8
Support for LITERAL+ extension.
Timo Sirainen <tss@iki.fi>
parents:
1014
diff
changeset
|
422 parser->error = "Expecting '}' after '+'"; |
09bac2875ed8
Support for LITERAL+ extension.
Timo Sirainen <tss@iki.fi>
parents:
1014
diff
changeset
|
423 return FALSE; |
09bac2875ed8
Support for LITERAL+ extension.
Timo Sirainen <tss@iki.fi>
parents:
1014
diff
changeset
|
424 } |
09bac2875ed8
Support for LITERAL+ extension.
Timo Sirainen <tss@iki.fi>
parents:
1014
diff
changeset
|
425 |
09bac2875ed8
Support for LITERAL+ extension.
Timo Sirainen <tss@iki.fi>
parents:
1014
diff
changeset
|
426 if (data[i] == '+') { |
09bac2875ed8
Support for LITERAL+ extension.
Timo Sirainen <tss@iki.fi>
parents:
1014
diff
changeset
|
427 parser->literal_nonsync = TRUE; |
09bac2875ed8
Support for LITERAL+ extension.
Timo Sirainen <tss@iki.fi>
parents:
1014
diff
changeset
|
428 continue; |
09bac2875ed8
Support for LITERAL+ extension.
Timo Sirainen <tss@iki.fi>
parents:
1014
diff
changeset
|
429 } |
09bac2875ed8
Support for LITERAL+ extension.
Timo Sirainen <tss@iki.fi>
parents:
1014
diff
changeset
|
430 |
717
3f817df5eba4
Input parsing was a bit broken in some conditions. Mostly visible with
Timo Sirainen <tss@iki.fi>
parents:
546
diff
changeset
|
431 if (data[i] < '0' || data[i] > '9') { |
768
8b3518bb327e
Limited max. command argument elements to 128. Added more verbose error
Timo Sirainen <tss@iki.fi>
parents:
764
diff
changeset
|
432 parser->error = "Invalid literal size"; |
0 | 433 return FALSE; |
717
3f817df5eba4
Input parsing was a bit broken in some conditions. Mostly visible with
Timo Sirainen <tss@iki.fi>
parents:
546
diff
changeset
|
434 } |
0 | 435 |
436 prev_size = parser->literal_size; | |
50
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
437 parser->literal_size = parser->literal_size*10 + (data[i]-'0'); |
0 | 438 |
439 if (parser->literal_size < prev_size) { | |
440 /* wrapped around, abort. */ | |
768
8b3518bb327e
Limited max. command argument elements to 128. Added more verbose error
Timo Sirainen <tss@iki.fi>
parents:
764
diff
changeset
|
441 parser->error = "Literal size too large"; |
0 | 442 return FALSE; |
443 } | |
444 } | |
445 | |
717
3f817df5eba4
Input parsing was a bit broken in some conditions. Mostly visible with
Timo Sirainen <tss@iki.fi>
parents:
546
diff
changeset
|
446 parser->cur_pos = i; |
3f817df5eba4
Input parsing was a bit broken in some conditions. Mostly visible with
Timo Sirainen <tss@iki.fi>
parents:
546
diff
changeset
|
447 return FALSE; |
0 | 448 } |
449 | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
450 static int imap_parser_read_literal_data(struct imap_parser *parser, |
898
0d5be52d7131
Use unsigned char* when accessing non-NUL terminating strings. Compiler
Timo Sirainen <tss@iki.fi>
parents:
896
diff
changeset
|
451 const unsigned char *data, |
184 | 452 size_t data_size) |
0 | 453 { |
454 if (parser->literal_skip_crlf) { | |
455 /* skip \r\n or \n, anything else gives an error */ | |
717
3f817df5eba4
Input parsing was a bit broken in some conditions. Mostly visible with
Timo Sirainen <tss@iki.fi>
parents:
546
diff
changeset
|
456 if (data_size == 0) |
3f817df5eba4
Input parsing was a bit broken in some conditions. Mostly visible with
Timo Sirainen <tss@iki.fi>
parents:
546
diff
changeset
|
457 return FALSE; |
3f817df5eba4
Input parsing was a bit broken in some conditions. Mostly visible with
Timo Sirainen <tss@iki.fi>
parents:
546
diff
changeset
|
458 |
0 | 459 if (*data == '\r') { |
1591
6eca99b727a0
IMAP parser memory limits are now enforced by bytes per line rather than
Timo Sirainen <tss@iki.fi>
parents:
1311
diff
changeset
|
460 parser->line_size++; |
0 | 461 data++; data_size--; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
735
diff
changeset
|
462 i_stream_skip(parser->input, 1); |
719 | 463 |
464 if (data_size == 0) | |
465 return FALSE; | |
0 | 466 } |
467 | |
717
3f817df5eba4
Input parsing was a bit broken in some conditions. Mostly visible with
Timo Sirainen <tss@iki.fi>
parents:
546
diff
changeset
|
468 if (*data != '\n') { |
768
8b3518bb327e
Limited max. command argument elements to 128. Added more verbose error
Timo Sirainen <tss@iki.fi>
parents:
764
diff
changeset
|
469 parser->error = "Missing LF after literal size"; |
0 | 470 return FALSE; |
717
3f817df5eba4
Input parsing was a bit broken in some conditions. Mostly visible with
Timo Sirainen <tss@iki.fi>
parents:
546
diff
changeset
|
471 } |
0 | 472 |
1591
6eca99b727a0
IMAP parser memory limits are now enforced by bytes per line rather than
Timo Sirainen <tss@iki.fi>
parents:
1311
diff
changeset
|
473 parser->line_size++; |
0 | 474 data++; data_size--; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
735
diff
changeset
|
475 i_stream_skip(parser->input, 1); |
1591
6eca99b727a0
IMAP parser memory limits are now enforced by bytes per line rather than
Timo Sirainen <tss@iki.fi>
parents:
1311
diff
changeset
|
476 |
0 | 477 parser->literal_skip_crlf = FALSE; |
478 | |
479 i_assert(parser->cur_pos == 0); | |
480 } | |
481 | |
6739
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
482 if ((parser->flags & IMAP_PARSE_FLAG_LITERAL_SIZE) == 0 || |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
483 parser->cur_type == ARG_PARSE_LITERAL_DATA_FORCED) { |
0 | 484 /* now we just wait until we've read enough data */ |
717
3f817df5eba4
Input parsing was a bit broken in some conditions. Mostly visible with
Timo Sirainen <tss@iki.fi>
parents:
546
diff
changeset
|
485 if (data_size < parser->literal_size) |
3f817df5eba4
Input parsing was a bit broken in some conditions. Mostly visible with
Timo Sirainen <tss@iki.fi>
parents:
546
diff
changeset
|
486 return FALSE; |
3f817df5eba4
Input parsing was a bit broken in some conditions. Mostly visible with
Timo Sirainen <tss@iki.fi>
parents:
546
diff
changeset
|
487 else { |
0 | 488 imap_parser_save_arg(parser, data, |
184 | 489 (size_t)parser->literal_size); |
444
85ab93a7693b
ImapArgList changed from linked list to array. easier to handle that way.
Timo Sirainen <tss@iki.fi>
parents:
424
diff
changeset
|
490 parser->cur_pos = (size_t)parser->literal_size; |
717
3f817df5eba4
Input parsing was a bit broken in some conditions. Mostly visible with
Timo Sirainen <tss@iki.fi>
parents:
546
diff
changeset
|
491 return TRUE; |
0 | 492 } |
493 } else { | |
494 /* we want to save only literal size, not the literal itself. */ | |
6739
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
495 parser->literal_size_return = TRUE; |
14629
c93ca5e46a8a
Marked functions parameters that are allowed to be NULL. Some APIs were also changed.
Timo Sirainen <tss@iki.fi>
parents:
14617
diff
changeset
|
496 imap_parser_save_arg(parser, &uchar_nul, 0); |
6739
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
497 return FALSE; |
0 | 498 } |
499 } | |
500 | |
15129
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
501 static bool imap_parser_is_next_resp_text(struct imap_parser *parser) |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
502 { |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
503 const struct imap_arg *arg; |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
504 |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
505 if (parser->cur_list != &parser->root_list || |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
506 array_count(parser->cur_list) != 1) |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
507 return FALSE; |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
508 |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
509 arg = array_idx(&parser->root_list, 0); |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
510 if (arg->type != IMAP_ARG_ATOM) |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
511 return FALSE; |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
512 |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
513 return strcasecmp(arg->_data.str, "OK") == 0 || |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
514 strcasecmp(arg->_data.str, "NO") == 0 || |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
515 strcasecmp(arg->_data.str, "BAD") == 0 || |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
516 strcasecmp(arg->_data.str, "BYE") == 0; |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
517 } |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
518 |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
519 static bool imap_parser_is_next_text(struct imap_parser *parser) |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
520 { |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
521 const struct imap_arg *arg; |
21322
5ab8dc1a4a6f
global: Change string position/length from unsigned int to size_t
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
522 size_t len; |
15129
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
523 |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
524 if (parser->cur_list != &parser->root_list) |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
525 return FALSE; |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
526 |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
527 arg = array_idx(&parser->root_list, array_count(&parser->root_list)-1); |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
528 if (arg->type != IMAP_ARG_ATOM) |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
529 return FALSE; |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
530 |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
531 len = strlen(arg->_data.str); |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
532 return len > 0 && arg->_data.str[len-1] == ']'; |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
533 } |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
534 |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
535 static bool imap_parser_read_text(struct imap_parser *parser, |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
536 const unsigned char *data, size_t data_size) |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
537 { |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
538 size_t i; |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
539 |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
540 /* read until end of line */ |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
541 for (i = parser->cur_pos; i < data_size; i++) { |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
542 if (is_linebreak(data[i])) { |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
543 imap_parser_save_arg(parser, data, i); |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
544 break; |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
545 } |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
546 } |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
547 parser->cur_pos = i; |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
548 return parser->cur_type == ARG_PARSE_NONE; |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
549 } |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
550 |
0 | 551 /* Returns TRUE if argument was fully processed. Also returns TRUE if |
552 an argument inside a list was processed. */ | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
553 static int imap_parser_read_arg(struct imap_parser *parser) |
0 | 554 { |
898
0d5be52d7131
Use unsigned char* when accessing non-NUL terminating strings. Compiler
Timo Sirainen <tss@iki.fi>
parents:
896
diff
changeset
|
555 const unsigned char *data; |
184 | 556 size_t data_size; |
0 | 557 |
898
0d5be52d7131
Use unsigned char* when accessing non-NUL terminating strings. Compiler
Timo Sirainen <tss@iki.fi>
parents:
896
diff
changeset
|
558 data = i_stream_get_data(parser->input, &data_size); |
0 | 559 if (data_size == 0) |
560 return FALSE; | |
561 | |
562 while (parser->cur_type == ARG_PARSE_NONE) { | |
563 /* we haven't started parsing yet */ | |
502
7927650f3b9b
imap_parser_read_args() didn't correctly always return "need for more data"
Timo Sirainen <tss@iki.fi>
parents:
469
diff
changeset
|
564 if (!imap_parser_skip_to_next(parser, &data, &data_size)) |
0 | 565 return FALSE; |
566 i_assert(parser->cur_pos == 0); | |
567 | |
15129
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
568 if (parser->cur_resp_text && |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
569 imap_parser_is_next_text(parser)) { |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
570 /* we just parsed [resp-text-code] */ |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
571 parser->cur_type = ARG_PARSE_TEXT; |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
572 break; |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
573 } |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
574 |
0 | 575 switch (data[0]) { |
576 case '\r': | |
9367
704917a65a16
imap-parser: Don't return early if line ends with CR but there's no LF.
Timo Sirainen <tss@iki.fi>
parents:
8837
diff
changeset
|
577 if (data_size == 1) { |
704917a65a16
imap-parser: Don't return early if line ends with CR but there's no LF.
Timo Sirainen <tss@iki.fi>
parents:
8837
diff
changeset
|
578 /* wait for LF */ |
704917a65a16
imap-parser: Don't return early if line ends with CR but there's no LF.
Timo Sirainen <tss@iki.fi>
parents:
8837
diff
changeset
|
579 return FALSE; |
704917a65a16
imap-parser: Don't return early if line ends with CR but there's no LF.
Timo Sirainen <tss@iki.fi>
parents:
8837
diff
changeset
|
580 } |
704917a65a16
imap-parser: Don't return early if line ends with CR but there's no LF.
Timo Sirainen <tss@iki.fi>
parents:
8837
diff
changeset
|
581 if (data[1] != '\n') { |
704917a65a16
imap-parser: Don't return early if line ends with CR but there's no LF.
Timo Sirainen <tss@iki.fi>
parents:
8837
diff
changeset
|
582 parser->error = "CR sent without LF"; |
704917a65a16
imap-parser: Don't return early if line ends with CR but there's no LF.
Timo Sirainen <tss@iki.fi>
parents:
8837
diff
changeset
|
583 return FALSE; |
704917a65a16
imap-parser: Don't return early if line ends with CR but there's no LF.
Timo Sirainen <tss@iki.fi>
parents:
8837
diff
changeset
|
584 } |
704917a65a16
imap-parser: Don't return early if line ends with CR but there's no LF.
Timo Sirainen <tss@iki.fi>
parents:
8837
diff
changeset
|
585 /* fall through */ |
0 | 586 case '\n': |
587 /* unexpected end of line */ | |
14589
c54dd35e1c0e
imap-parser: Added IMAP_PARSE_FLAG_INSIDE_LIST flag.
Stephan Bosch <stephan@rename-it.nl>
parents:
14133
diff
changeset
|
588 if ((parser->flags & IMAP_PARSE_FLAG_INSIDE_LIST) != 0) { |
c54dd35e1c0e
imap-parser: Added IMAP_PARSE_FLAG_INSIDE_LIST flag.
Stephan Bosch <stephan@rename-it.nl>
parents:
14133
diff
changeset
|
589 parser->error = "Missing ')'"; |
c54dd35e1c0e
imap-parser: Added IMAP_PARSE_FLAG_INSIDE_LIST flag.
Stephan Bosch <stephan@rename-it.nl>
parents:
14133
diff
changeset
|
590 return FALSE; |
c54dd35e1c0e
imap-parser: Added IMAP_PARSE_FLAG_INSIDE_LIST flag.
Stephan Bosch <stephan@rename-it.nl>
parents:
14133
diff
changeset
|
591 } |
0 | 592 parser->eol = TRUE; |
593 return FALSE; | |
594 case '"': | |
595 parser->cur_type = ARG_PARSE_STRING; | |
596 parser->str_first_escape = -1; | |
597 break; | |
14607
68a8b650578e
imap parser: Added support for parsing literal8 (for BINARY extension)
Timo Sirainen <tss@iki.fi>
parents:
14589
diff
changeset
|
598 case '~': |
17337
8568cacb0d03
lib-imap: IMAP parser didn't parse atoms correctly that started with '~' character.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
599 /* This could be either literal8 or atom */ |
8568cacb0d03
lib-imap: IMAP parser didn't parse atoms correctly that started with '~' character.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
600 if (data_size == 1) { |
8568cacb0d03
lib-imap: IMAP parser didn't parse atoms correctly that started with '~' character.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
601 /* wait for the next char */ |
8568cacb0d03
lib-imap: IMAP parser didn't parse atoms correctly that started with '~' character.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
602 return FALSE; |
8568cacb0d03
lib-imap: IMAP parser didn't parse atoms correctly that started with '~' character.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
603 } |
8568cacb0d03
lib-imap: IMAP parser didn't parse atoms correctly that started with '~' character.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
604 if (data[1] != '{') { |
8568cacb0d03
lib-imap: IMAP parser didn't parse atoms correctly that started with '~' character.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
605 parser->cur_type = ARG_PARSE_ATOM; |
8568cacb0d03
lib-imap: IMAP parser didn't parse atoms correctly that started with '~' character.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
606 break; |
8568cacb0d03
lib-imap: IMAP parser didn't parse atoms correctly that started with '~' character.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
607 } |
14617
c14c58bedafe
imap parser: literal8 flag was handled in opposite way.
Timo Sirainen <tss@iki.fi>
parents:
14607
diff
changeset
|
608 if ((parser->flags & IMAP_PARSE_FLAG_LITERAL8) == 0) { |
14607
68a8b650578e
imap parser: Added support for parsing literal8 (for BINARY extension)
Timo Sirainen <tss@iki.fi>
parents:
14589
diff
changeset
|
609 parser->error = "literal8 not allowed here"; |
68a8b650578e
imap parser: Added support for parsing literal8 (for BINARY extension)
Timo Sirainen <tss@iki.fi>
parents:
14589
diff
changeset
|
610 return FALSE; |
68a8b650578e
imap parser: Added support for parsing literal8 (for BINARY extension)
Timo Sirainen <tss@iki.fi>
parents:
14589
diff
changeset
|
611 } |
68a8b650578e
imap parser: Added support for parsing literal8 (for BINARY extension)
Timo Sirainen <tss@iki.fi>
parents:
14589
diff
changeset
|
612 parser->cur_type = ARG_PARSE_LITERAL8; |
68a8b650578e
imap parser: Added support for parsing literal8 (for BINARY extension)
Timo Sirainen <tss@iki.fi>
parents:
14589
diff
changeset
|
613 parser->literal_size = 0; |
68a8b650578e
imap parser: Added support for parsing literal8 (for BINARY extension)
Timo Sirainen <tss@iki.fi>
parents:
14589
diff
changeset
|
614 parser->literal_nonsync = FALSE; |
68a8b650578e
imap parser: Added support for parsing literal8 (for BINARY extension)
Timo Sirainen <tss@iki.fi>
parents:
14589
diff
changeset
|
615 parser->literal8 = TRUE; |
68a8b650578e
imap parser: Added support for parsing literal8 (for BINARY extension)
Timo Sirainen <tss@iki.fi>
parents:
14589
diff
changeset
|
616 break; |
0 | 617 case '{': |
618 parser->cur_type = ARG_PARSE_LITERAL; | |
619 parser->literal_size = 0; | |
1022
09bac2875ed8
Support for LITERAL+ extension.
Timo Sirainen <tss@iki.fi>
parents:
1014
diff
changeset
|
620 parser->literal_nonsync = FALSE; |
14607
68a8b650578e
imap parser: Added support for parsing literal8 (for BINARY extension)
Timo Sirainen <tss@iki.fi>
parents:
14589
diff
changeset
|
621 parser->literal8 = FALSE; |
0 | 622 break; |
623 case '(': | |
624 imap_parser_open_list(parser); | |
16915
0c4ee3b9fa3b
lib-imap: Added IMAP_PARSE_FLAG_STOP_AT_LIST for stopping after '('
Timo Sirainen <tss@iki.fi>
parents:
16914
diff
changeset
|
625 if ((parser->flags & IMAP_PARSE_FLAG_STOP_AT_LIST) != 0) { |
0c4ee3b9fa3b
lib-imap: Added IMAP_PARSE_FLAG_STOP_AT_LIST for stopping after '('
Timo Sirainen <tss@iki.fi>
parents:
16914
diff
changeset
|
626 i_stream_skip(parser->input, 1); |
0c4ee3b9fa3b
lib-imap: Added IMAP_PARSE_FLAG_STOP_AT_LIST for stopping after '('
Timo Sirainen <tss@iki.fi>
parents:
16914
diff
changeset
|
627 return FALSE; |
0c4ee3b9fa3b
lib-imap: Added IMAP_PARSE_FLAG_STOP_AT_LIST for stopping after '('
Timo Sirainen <tss@iki.fi>
parents:
16914
diff
changeset
|
628 } |
0 | 629 break; |
630 case ')': | |
631 if (!imap_parser_close_list(parser)) | |
632 return FALSE; | |
633 | |
444
85ab93a7693b
ImapArgList changed from linked list to array. easier to handle that way.
Timo Sirainen <tss@iki.fi>
parents:
424
diff
changeset
|
634 if (parser->list_arg == NULL) { |
0 | 635 /* end of argument */ |
636 parser->cur_pos++; | |
637 return TRUE; | |
638 } | |
639 break; | |
640 default: | |
1169
0eaf51e01ccd
Allow wildcards anyway in atoms, they're needed with LIST.
Timo Sirainen <tss@iki.fi>
parents:
1167
diff
changeset
|
641 if (!is_valid_atom_char(parser, data[0])) |
0eaf51e01ccd
Allow wildcards anyway in atoms, they're needed with LIST.
Timo Sirainen <tss@iki.fi>
parents:
1167
diff
changeset
|
642 return FALSE; |
0 | 643 parser->cur_type = ARG_PARSE_ATOM; |
644 break; | |
645 } | |
646 | |
647 parser->cur_pos++; | |
648 } | |
649 | |
650 i_assert(data_size > 0); | |
651 | |
652 switch (parser->cur_type) { | |
653 case ARG_PARSE_ATOM: | |
654 if (!imap_parser_read_atom(parser, data, data_size)) | |
655 return FALSE; | |
15129
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
656 if ((parser->flags & IMAP_PARSE_FLAG_SERVER_TEXT) == 0) |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
657 break; |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
658 |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
659 if (imap_parser_is_next_resp_text(parser)) { |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
660 /* we just parsed OK/NO/BAD/BYE. after parsing the |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
661 [resp-text-code] the rest of the message can contain |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
662 pretty much any random text, which we can't parse |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
663 as if it was valid IMAP input */ |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
664 parser->cur_resp_text = TRUE; |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
665 } |
0 | 666 break; |
667 case ARG_PARSE_STRING: | |
668 if (!imap_parser_read_string(parser, data, data_size)) | |
669 return FALSE; | |
670 break; | |
14607
68a8b650578e
imap parser: Added support for parsing literal8 (for BINARY extension)
Timo Sirainen <tss@iki.fi>
parents:
14589
diff
changeset
|
671 case ARG_PARSE_LITERAL8: |
68a8b650578e
imap parser: Added support for parsing literal8 (for BINARY extension)
Timo Sirainen <tss@iki.fi>
parents:
14589
diff
changeset
|
672 if (parser->cur_pos == data_size) |
68a8b650578e
imap parser: Added support for parsing literal8 (for BINARY extension)
Timo Sirainen <tss@iki.fi>
parents:
14589
diff
changeset
|
673 return FALSE; |
68a8b650578e
imap parser: Added support for parsing literal8 (for BINARY extension)
Timo Sirainen <tss@iki.fi>
parents:
14589
diff
changeset
|
674 if (data[parser->cur_pos] != '{') { |
68a8b650578e
imap parser: Added support for parsing literal8 (for BINARY extension)
Timo Sirainen <tss@iki.fi>
parents:
14589
diff
changeset
|
675 parser->error = "Expected '{'"; |
68a8b650578e
imap parser: Added support for parsing literal8 (for BINARY extension)
Timo Sirainen <tss@iki.fi>
parents:
14589
diff
changeset
|
676 return FALSE; |
68a8b650578e
imap parser: Added support for parsing literal8 (for BINARY extension)
Timo Sirainen <tss@iki.fi>
parents:
14589
diff
changeset
|
677 } |
16520
dd04b4ef530d
lib-imap: Fixed parsing literal8 in some situations.
Timo Sirainen <tss@iki.fi>
parents:
16335
diff
changeset
|
678 parser->cur_type = ARG_PARSE_LITERAL; |
14607
68a8b650578e
imap parser: Added support for parsing literal8 (for BINARY extension)
Timo Sirainen <tss@iki.fi>
parents:
14589
diff
changeset
|
679 parser->cur_pos++; |
68a8b650578e
imap parser: Added support for parsing literal8 (for BINARY extension)
Timo Sirainen <tss@iki.fi>
parents:
14589
diff
changeset
|
680 /* fall through */ |
0 | 681 case ARG_PARSE_LITERAL: |
682 if (!imap_parser_read_literal(parser, data, data_size)) | |
683 return FALSE; | |
684 | |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
735
diff
changeset
|
685 /* pass through to parsing data. since input->skip was |
0 | 686 modified, we need to get the data start position again. */ |
898
0d5be52d7131
Use unsigned char* when accessing non-NUL terminating strings. Compiler
Timo Sirainen <tss@iki.fi>
parents:
896
diff
changeset
|
687 data = i_stream_get_data(parser->input, &data_size); |
444
85ab93a7693b
ImapArgList changed from linked list to array. easier to handle that way.
Timo Sirainen <tss@iki.fi>
parents:
424
diff
changeset
|
688 |
85ab93a7693b
ImapArgList changed from linked list to array. easier to handle that way.
Timo Sirainen <tss@iki.fi>
parents:
424
diff
changeset
|
689 /* fall through */ |
0 | 690 case ARG_PARSE_LITERAL_DATA: |
6739
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
691 case ARG_PARSE_LITERAL_DATA_FORCED: |
717
3f817df5eba4
Input parsing was a bit broken in some conditions. Mostly visible with
Timo Sirainen <tss@iki.fi>
parents:
546
diff
changeset
|
692 if (!imap_parser_read_literal_data(parser, data, data_size)) |
3f817df5eba4
Input parsing was a bit broken in some conditions. Mostly visible with
Timo Sirainen <tss@iki.fi>
parents:
546
diff
changeset
|
693 return FALSE; |
0 | 694 break; |
15129
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
695 case ARG_PARSE_TEXT: |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
696 if (!imap_parser_read_text(parser, data, data_size)) |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
697 return FALSE; |
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
698 break; |
0 | 699 default: |
546
e1254b838e0b
Added --enable-asserts (default) and fixed some warnings when building
Timo Sirainen <tss@iki.fi>
parents:
504
diff
changeset
|
700 i_unreached(); |
0 | 701 } |
702 | |
717
3f817df5eba4
Input parsing was a bit broken in some conditions. Mostly visible with
Timo Sirainen <tss@iki.fi>
parents:
546
diff
changeset
|
703 i_assert(parser->cur_type == ARG_PARSE_NONE); |
3f817df5eba4
Input parsing was a bit broken in some conditions. Mostly visible with
Timo Sirainen <tss@iki.fi>
parents:
546
diff
changeset
|
704 return TRUE; |
0 | 705 } |
706 | |
1010
3c30228ae095
Missing ')' wasn't reported correctly.
Timo Sirainen <tss@iki.fi>
parents:
941
diff
changeset
|
707 /* ARG_PARSE_NONE checks that last argument isn't only partially parsed. */ |
720 | 708 #define IS_UNFINISHED(parser) \ |
709 ((parser)->cur_type != ARG_PARSE_NONE || \ | |
16915
0c4ee3b9fa3b
lib-imap: Added IMAP_PARSE_FLAG_STOP_AT_LIST for stopping after '('
Timo Sirainen <tss@iki.fi>
parents:
16914
diff
changeset
|
710 ((parser)->cur_list != &parser->root_list && \ |
0c4ee3b9fa3b
lib-imap: Added IMAP_PARSE_FLAG_STOP_AT_LIST for stopping after '('
Timo Sirainen <tss@iki.fi>
parents:
16914
diff
changeset
|
711 ((parser)->flags & IMAP_PARSE_FLAG_STOP_AT_LIST) == 0)) |
719 | 712 |
1661
566fb4bf7066
Fixes for parsing BODYSTRUCTURE
Timo Sirainen <tss@iki.fi>
parents:
1591
diff
changeset
|
713 static int finish_line(struct imap_parser *parser, unsigned int count, |
5835
d59ed6a31b66
Added more consts to imap-parser API
Timo Sirainen <tss@iki.fi>
parents:
5024
diff
changeset
|
714 const struct imap_arg **args_r) |
1661
566fb4bf7066
Fixes for parsing BODYSTRUCTURE
Timo Sirainen <tss@iki.fi>
parents:
1591
diff
changeset
|
715 { |
5836
9f869a7a3d73
Changed imap-parser API to use standard arrays for lists instead of its own
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
716 struct imap_arg *arg; |
9503
fd7d2cb8fda6
imap_parser_read_args() didn't correctly return how many parameters were read.
Timo Sirainen <tss@iki.fi>
parents:
9367
diff
changeset
|
717 int ret = array_count(&parser->root_list); |
5836
9f869a7a3d73
Changed imap-parser API to use standard arrays for lists instead of its own
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
718 |
1661
566fb4bf7066
Fixes for parsing BODYSTRUCTURE
Timo Sirainen <tss@iki.fi>
parents:
1591
diff
changeset
|
719 parser->line_size += parser->cur_pos; |
566fb4bf7066
Fixes for parsing BODYSTRUCTURE
Timo Sirainen <tss@iki.fi>
parents:
1591
diff
changeset
|
720 i_stream_skip(parser->input, parser->cur_pos); |
566fb4bf7066
Fixes for parsing BODYSTRUCTURE
Timo Sirainen <tss@iki.fi>
parents:
1591
diff
changeset
|
721 parser->cur_pos = 0; |
15129
382df961f290
lib-imap: Added IMAP_PARSE_FLAG_SERVER_TEXT that fixes parsing input from IMAP server.
Timo Sirainen <tss@iki.fi>
parents:
15127
diff
changeset
|
722 parser->cur_resp_text = FALSE; |
1661
566fb4bf7066
Fixes for parsing BODYSTRUCTURE
Timo Sirainen <tss@iki.fi>
parents:
1591
diff
changeset
|
723 |
16915
0c4ee3b9fa3b
lib-imap: Added IMAP_PARSE_FLAG_STOP_AT_LIST for stopping after '('
Timo Sirainen <tss@iki.fi>
parents:
16914
diff
changeset
|
724 if (parser->list_arg != NULL && !parser->literal_size_return && |
0c4ee3b9fa3b
lib-imap: Added IMAP_PARSE_FLAG_STOP_AT_LIST for stopping after '('
Timo Sirainen <tss@iki.fi>
parents:
16914
diff
changeset
|
725 (parser->flags & IMAP_PARSE_FLAG_STOP_AT_LIST) == 0) { |
1661
566fb4bf7066
Fixes for parsing BODYSTRUCTURE
Timo Sirainen <tss@iki.fi>
parents:
1591
diff
changeset
|
726 parser->error = "Missing ')'"; |
5835
d59ed6a31b66
Added more consts to imap-parser API
Timo Sirainen <tss@iki.fi>
parents:
5024
diff
changeset
|
727 *args_r = NULL; |
1661
566fb4bf7066
Fixes for parsing BODYSTRUCTURE
Timo Sirainen <tss@iki.fi>
parents:
1591
diff
changeset
|
728 return -1; |
566fb4bf7066
Fixes for parsing BODYSTRUCTURE
Timo Sirainen <tss@iki.fi>
parents:
1591
diff
changeset
|
729 } |
566fb4bf7066
Fixes for parsing BODYSTRUCTURE
Timo Sirainen <tss@iki.fi>
parents:
1591
diff
changeset
|
730 |
5836
9f869a7a3d73
Changed imap-parser API to use standard arrays for lists instead of its own
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
731 arg = array_append_space(&parser->root_list); |
9f869a7a3d73
Changed imap-parser API to use standard arrays for lists instead of its own
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
732 arg->type = IMAP_ARG_EOL; |
16335
67ec8bb5c27a
lib-imap: imap_parser_read_args() shouldn't append multiple EOLs when calling multiple times.
Timo Sirainen <tss@iki.fi>
parents:
15715
diff
changeset
|
733 parser->args_added_extra_eol = TRUE; |
14979
e0a3812771fd
imap-parser: Allow calling imap_parser_read_args() multiple times with larger count parameter.
Timo Sirainen <tss@iki.fi>
parents:
14978
diff
changeset
|
734 |
5836
9f869a7a3d73
Changed imap-parser API to use standard arrays for lists instead of its own
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
735 *args_r = array_get(&parser->root_list, &count); |
9503
fd7d2cb8fda6
imap_parser_read_args() didn't correctly return how many parameters were read.
Timo Sirainen <tss@iki.fi>
parents:
9367
diff
changeset
|
736 return ret; |
1661
566fb4bf7066
Fixes for parsing BODYSTRUCTURE
Timo Sirainen <tss@iki.fi>
parents:
1591
diff
changeset
|
737 } |
566fb4bf7066
Fixes for parsing BODYSTRUCTURE
Timo Sirainen <tss@iki.fi>
parents:
1591
diff
changeset
|
738 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
739 int imap_parser_read_args(struct imap_parser *parser, unsigned int count, |
5835
d59ed6a31b66
Added more consts to imap-parser API
Timo Sirainen <tss@iki.fi>
parents:
5024
diff
changeset
|
740 enum imap_parser_flags flags, |
d59ed6a31b66
Added more consts to imap-parser API
Timo Sirainen <tss@iki.fi>
parents:
5024
diff
changeset
|
741 const struct imap_arg **args_r) |
0 | 742 { |
743 parser->flags = flags; | |
744 | |
14979
e0a3812771fd
imap-parser: Allow calling imap_parser_read_args() multiple times with larger count parameter.
Timo Sirainen <tss@iki.fi>
parents:
14978
diff
changeset
|
745 if (parser->args_added_extra_eol) { |
6739
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
746 /* delete EOL */ |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
747 array_delete(&parser->root_list, |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
748 array_count(&parser->root_list)-1, 1); |
14979
e0a3812771fd
imap-parser: Allow calling imap_parser_read_args() multiple times with larger count parameter.
Timo Sirainen <tss@iki.fi>
parents:
14978
diff
changeset
|
749 parser->args_added_extra_eol = FALSE; |
6739
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
750 parser->literal_size_return = FALSE; |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
751 } |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
752 |
5836
9f869a7a3d73
Changed imap-parser API to use standard arrays for lists instead of its own
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
753 while (!parser->eol && (count == 0 || IS_UNFINISHED(parser) || |
9f869a7a3d73
Changed imap-parser API to use standard arrays for lists instead of its own
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
754 array_count(&parser->root_list) < count)) { |
444
85ab93a7693b
ImapArgList changed from linked list to array. easier to handle that way.
Timo Sirainen <tss@iki.fi>
parents:
424
diff
changeset
|
755 if (!imap_parser_read_arg(parser)) |
0 | 756 break; |
768
8b3518bb327e
Limited max. command argument elements to 128. Added more verbose error
Timo Sirainen <tss@iki.fi>
parents:
764
diff
changeset
|
757 |
1591
6eca99b727a0
IMAP parser memory limits are now enforced by bytes per line rather than
Timo Sirainen <tss@iki.fi>
parents:
1311
diff
changeset
|
758 if (parser->line_size > parser->max_line_size) { |
6eca99b727a0
IMAP parser memory limits are now enforced by bytes per line rather than
Timo Sirainen <tss@iki.fi>
parents:
1311
diff
changeset
|
759 parser->error = "IMAP command line too large"; |
768
8b3518bb327e
Limited max. command argument elements to 128. Added more verbose error
Timo Sirainen <tss@iki.fi>
parents:
764
diff
changeset
|
760 break; |
8b3518bb327e
Limited max. command argument elements to 128. Added more verbose error
Timo Sirainen <tss@iki.fi>
parents:
764
diff
changeset
|
761 } |
0 | 762 } |
763 | |
768
8b3518bb327e
Limited max. command argument elements to 128. Added more verbose error
Timo Sirainen <tss@iki.fi>
parents:
764
diff
changeset
|
764 if (parser->error != NULL) { |
0 | 765 /* error, abort */ |
1591
6eca99b727a0
IMAP parser memory limits are now enforced by bytes per line rather than
Timo Sirainen <tss@iki.fi>
parents:
1311
diff
changeset
|
766 parser->line_size += parser->cur_pos; |
1014
26a028e6d7d5
Externally parsed literal size always stops argument parsing now. Input
Timo Sirainen <tss@iki.fi>
parents:
1010
diff
changeset
|
767 i_stream_skip(parser->input, parser->cur_pos); |
26a028e6d7d5
Externally parsed literal size always stops argument parsing now. Input
Timo Sirainen <tss@iki.fi>
parents:
1010
diff
changeset
|
768 parser->cur_pos = 0; |
5835
d59ed6a31b66
Added more consts to imap-parser API
Timo Sirainen <tss@iki.fi>
parents:
5024
diff
changeset
|
769 *args_r = NULL; |
0 | 770 return -1; |
735
ce93054db96b
All SEARCH arguments still may not have been parsed.
Timo Sirainen <tss@iki.fi>
parents:
720
diff
changeset
|
771 } else if ((!IS_UNFINISHED(parser) && count > 0 && |
6739
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
772 array_count(&parser->root_list) >= count) || |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
773 parser->eol || parser->literal_size_return) { |
1010
3c30228ae095
Missing ')' wasn't reported correctly.
Timo Sirainen <tss@iki.fi>
parents:
941
diff
changeset
|
774 /* all arguments read / end of line. */ |
5835
d59ed6a31b66
Added more consts to imap-parser API
Timo Sirainen <tss@iki.fi>
parents:
5024
diff
changeset
|
775 return finish_line(parser, count, args_r); |
0 | 776 } else { |
777 /* need more data */ | |
5835
d59ed6a31b66
Added more consts to imap-parser API
Timo Sirainen <tss@iki.fi>
parents:
5024
diff
changeset
|
778 *args_r = NULL; |
0 | 779 return -2; |
780 } | |
781 } | |
782 | |
6739
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
783 static struct imap_arg * |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
784 imap_parser_get_last_literal_size(struct imap_parser *parser, |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
785 ARRAY_TYPE(imap_arg_list) **list_r) |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
786 { |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
787 ARRAY_TYPE(imap_arg_list) *list; |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
788 struct imap_arg *args; |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
789 unsigned int count; |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
790 |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
791 list = &parser->root_list; |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
792 args = array_get_modifiable(&parser->root_list, &count); |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
793 i_assert(count > 1 && args[count-1].type == IMAP_ARG_EOL); |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
794 count--; |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
795 |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
796 while (args[count-1].type != IMAP_ARG_LITERAL_SIZE && |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
797 args[count-1].type != IMAP_ARG_LITERAL_SIZE_NONSYNC) { |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
798 if (args[count-1].type != IMAP_ARG_LIST) |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
799 return NULL; |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
800 |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
801 /* maybe the list ends with literal size */ |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
802 list = &args[count-1]._data.list; |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
803 args = array_get_modifiable(list, &count); |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
804 if (count == 0) |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
805 return NULL; |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
806 } |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
807 |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
808 *list_r = list; |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
809 return &args[count-1]; |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
810 } |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
811 |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
812 bool imap_parser_get_literal_size(struct imap_parser *parser, uoff_t *size_r) |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
813 { |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
814 ARRAY_TYPE(imap_arg_list) *list; |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
815 struct imap_arg *last_arg; |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
816 |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
817 last_arg = imap_parser_get_last_literal_size(parser, &list); |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
818 if (last_arg == NULL) |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
819 return FALSE; |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
820 |
11063
dbc864c0cff7
lib-imap: Changed imap_arg accessing APIs.
Timo Sirainen <tss@iki.fi>
parents:
10697
diff
changeset
|
821 return imap_arg_get_literal_size(last_arg, size_r); |
6739
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
822 } |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
823 |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
824 void imap_parser_read_last_literal(struct imap_parser *parser) |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
825 { |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
826 ARRAY_TYPE(imap_arg_list) *list; |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
827 struct imap_arg *last_arg; |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
828 |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
829 i_assert(parser->literal_size_return); |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
830 |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
831 last_arg = imap_parser_get_last_literal_size(parser, &list); |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
832 i_assert(last_arg != NULL); |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
833 |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
834 parser->cur_type = ARG_PARSE_LITERAL_DATA_FORCED; |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
835 i_assert(parser->literal_size == last_arg->_data.literal_size); |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
836 |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
837 /* delete EOL */ |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
838 array_delete(&parser->root_list, array_count(&parser->root_list)-1, 1); |
14982
6c0ba0348e85
imap-parser: Fixed imap_parser_read_last_literal() to work again
Timo Sirainen <tss@iki.fi>
parents:
14979
diff
changeset
|
839 parser->args_added_extra_eol = FALSE; |
6739
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
840 |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
841 /* delete literal size */ |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
842 array_delete(list, array_count(list)-1, 1); |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
843 parser->literal_size_return = FALSE; |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
844 } |
d145669ed45a
Added imap_parser_get_literal_size() and imap_parser_read_last_literal() to
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
845 |
1661
566fb4bf7066
Fixes for parsing BODYSTRUCTURE
Timo Sirainen <tss@iki.fi>
parents:
1591
diff
changeset
|
846 int imap_parser_finish_line(struct imap_parser *parser, unsigned int count, |
566fb4bf7066
Fixes for parsing BODYSTRUCTURE
Timo Sirainen <tss@iki.fi>
parents:
1591
diff
changeset
|
847 enum imap_parser_flags flags, |
5835
d59ed6a31b66
Added more consts to imap-parser API
Timo Sirainen <tss@iki.fi>
parents:
5024
diff
changeset
|
848 const struct imap_arg **args_r) |
1661
566fb4bf7066
Fixes for parsing BODYSTRUCTURE
Timo Sirainen <tss@iki.fi>
parents:
1591
diff
changeset
|
849 { |
566fb4bf7066
Fixes for parsing BODYSTRUCTURE
Timo Sirainen <tss@iki.fi>
parents:
1591
diff
changeset
|
850 const unsigned char *data; |
566fb4bf7066
Fixes for parsing BODYSTRUCTURE
Timo Sirainen <tss@iki.fi>
parents:
1591
diff
changeset
|
851 size_t data_size; |
566fb4bf7066
Fixes for parsing BODYSTRUCTURE
Timo Sirainen <tss@iki.fi>
parents:
1591
diff
changeset
|
852 int ret; |
566fb4bf7066
Fixes for parsing BODYSTRUCTURE
Timo Sirainen <tss@iki.fi>
parents:
1591
diff
changeset
|
853 |
5835
d59ed6a31b66
Added more consts to imap-parser API
Timo Sirainen <tss@iki.fi>
parents:
5024
diff
changeset
|
854 ret = imap_parser_read_args(parser, count, flags, args_r); |
12810
3f21260a72ce
lib-imap: imap_parser_finish_line() didn't return failure on invalid input.
Timo Sirainen <tss@iki.fi>
parents:
11345
diff
changeset
|
855 if (ret == -1) |
3f21260a72ce
lib-imap: imap_parser_finish_line() didn't return failure on invalid input.
Timo Sirainen <tss@iki.fi>
parents:
11345
diff
changeset
|
856 return -1; |
1661
566fb4bf7066
Fixes for parsing BODYSTRUCTURE
Timo Sirainen <tss@iki.fi>
parents:
1591
diff
changeset
|
857 if (ret == -2) { |
566fb4bf7066
Fixes for parsing BODYSTRUCTURE
Timo Sirainen <tss@iki.fi>
parents:
1591
diff
changeset
|
858 /* we should have noticed end of everything except atom */ |
566fb4bf7066
Fixes for parsing BODYSTRUCTURE
Timo Sirainen <tss@iki.fi>
parents:
1591
diff
changeset
|
859 if (parser->cur_type == ARG_PARSE_ATOM) { |
566fb4bf7066
Fixes for parsing BODYSTRUCTURE
Timo Sirainen <tss@iki.fi>
parents:
1591
diff
changeset
|
860 data = i_stream_get_data(parser->input, &data_size); |
566fb4bf7066
Fixes for parsing BODYSTRUCTURE
Timo Sirainen <tss@iki.fi>
parents:
1591
diff
changeset
|
861 imap_parser_save_arg(parser, data, data_size); |
566fb4bf7066
Fixes for parsing BODYSTRUCTURE
Timo Sirainen <tss@iki.fi>
parents:
1591
diff
changeset
|
862 } |
566fb4bf7066
Fixes for parsing BODYSTRUCTURE
Timo Sirainen <tss@iki.fi>
parents:
1591
diff
changeset
|
863 } |
5835
d59ed6a31b66
Added more consts to imap-parser API
Timo Sirainen <tss@iki.fi>
parents:
5024
diff
changeset
|
864 return finish_line(parser, count, args_r); |
1661
566fb4bf7066
Fixes for parsing BODYSTRUCTURE
Timo Sirainen <tss@iki.fi>
parents:
1591
diff
changeset
|
865 } |
566fb4bf7066
Fixes for parsing BODYSTRUCTURE
Timo Sirainen <tss@iki.fi>
parents:
1591
diff
changeset
|
866 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
867 const char *imap_parser_read_word(struct imap_parser *parser) |
0 | 868 { |
898
0d5be52d7131
Use unsigned char* when accessing non-NUL terminating strings. Compiler
Timo Sirainen <tss@iki.fi>
parents:
896
diff
changeset
|
869 const unsigned char *data; |
184 | 870 size_t i, data_size; |
0 | 871 |
898
0d5be52d7131
Use unsigned char* when accessing non-NUL terminating strings. Compiler
Timo Sirainen <tss@iki.fi>
parents:
896
diff
changeset
|
872 data = i_stream_get_data(parser->input, &data_size); |
0 | 873 |
874 for (i = 0; i < data_size; i++) { | |
875 if (data[i] == ' ' || data[i] == '\r' || data[i] == '\n') | |
876 break; | |
877 } | |
878 | |
879 if (i < data_size) { | |
1591
6eca99b727a0
IMAP parser memory limits are now enforced by bytes per line rather than
Timo Sirainen <tss@iki.fi>
parents:
1311
diff
changeset
|
880 data_size = i + (data[i] == ' ' ? 1 : 0); |
6eca99b727a0
IMAP parser memory limits are now enforced by bytes per line rather than
Timo Sirainen <tss@iki.fi>
parents:
1311
diff
changeset
|
881 parser->line_size += data_size; |
6eca99b727a0
IMAP parser memory limits are now enforced by bytes per line rather than
Timo Sirainen <tss@iki.fi>
parents:
1311
diff
changeset
|
882 i_stream_skip(parser->input, data_size); |
0 | 883 return p_strndup(parser->pool, data, i); |
884 } else { | |
885 return NULL; | |
886 } | |
887 } |