Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/lib-mail/message-parser.c @ 1689:c07b98265577 HEAD
If BODY/BODYSTRUCTURE is requested with some other headers, parse the
headers only once. If body contains multiple MIME parts, cache the internal
MIME structure so BODY[part] fetching doesn't need to parse it again.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 20 Aug 2003 04:41:30 +0300 |
parents | aff92c2de6f5 |
children | ef79ce6507ff |
rev | line source |
---|---|
0 | 1 /* Copyright (C) 2002 Timo Sirainen */ |
2 | |
3 #include "lib.h" | |
1322
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
4 #include "buffer.h" |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
5 #include "istream.h" |
1322
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
6 #include "str.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:
874
diff
changeset
|
7 #include "strescape.h" |
0 | 8 #include "message-content-parser.h" |
9 #include "message-parser.h" | |
9
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
7
diff
changeset
|
10 #include "message-size.h" |
0 | 11 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
12 struct message_boundary { |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
13 struct message_boundary *next; |
0 | 14 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
15 struct message_part *part; |
0 | 16 const char *boundary; |
184 | 17 size_t len; |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
18 }; |
0 | 19 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
20 struct parser_context { |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
21 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
|
22 struct message_part *part; |
0 | 23 |
24 char *last_boundary; | |
25 char *last_content_type; | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
26 struct message_boundary *boundaries; |
0 | 27 |
1038
60646878858e
Function typedefs now define them as functions, not function pointers.
Timo Sirainen <tss@iki.fi>
parents:
953
diff
changeset
|
28 message_header_callback_t *callback; |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
29 void *context; |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
30 }; |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
31 |
1322
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
32 struct message_header_parser_ctx { |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
33 struct message_header_line line; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
34 |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
35 struct istream *input; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
36 struct message_size *hdr_size; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
37 |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
38 string_t *name; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
39 buffer_t *value_buf; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
40 size_t skip; |
1534
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
41 |
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
42 int has_nuls; |
1322
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
43 }; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
44 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
45 static struct message_part * |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
46 message_parse_part(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
|
47 struct parser_context *parser_ctx); |
0 | 48 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
49 static struct message_part * |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
50 message_parse_body(struct istream *input, struct message_boundary *boundaries, |
1534
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
51 struct message_size *body_size, int *has_nuls); |
0 | 52 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
53 static struct message_part * |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
54 message_skip_boundary(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
|
55 struct message_boundary *boundaries, |
1534
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
56 struct message_size *boundary_size, int *has_nuls); |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
57 |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
58 static void message_size_add_part(struct message_size *dest, |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
59 struct message_part *part) |
0 | 60 { |
61 dest->physical_size += | |
62 part->header_size.physical_size + | |
63 part->body_size.physical_size; | |
64 dest->virtual_size += | |
65 part->header_size.virtual_size + | |
66 part->body_size.virtual_size; | |
67 dest->lines += part->header_size.lines + part->body_size.lines; | |
68 } | |
69 | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
70 static struct message_part * |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
71 message_part_append(pool_t pool, struct message_part *parent) |
0 | 72 { |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
73 struct message_part *part, **list; |
0 | 74 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
75 part = p_new(pool, struct message_part, 1); |
0 | 76 part->parent = parent; |
77 | |
212
4327b1266604
message/rfc822 mime parts weren't parsed correctly
Timo Sirainen <tss@iki.fi>
parents:
184
diff
changeset
|
78 /* set child position */ |
4327b1266604
message/rfc822 mime parts weren't parsed correctly
Timo Sirainen <tss@iki.fi>
parents:
184
diff
changeset
|
79 part->physical_pos = |
4327b1266604
message/rfc822 mime parts weren't parsed correctly
Timo Sirainen <tss@iki.fi>
parents:
184
diff
changeset
|
80 parent->physical_pos + |
4327b1266604
message/rfc822 mime parts weren't parsed correctly
Timo Sirainen <tss@iki.fi>
parents:
184
diff
changeset
|
81 parent->body_size.physical_size + |
4327b1266604
message/rfc822 mime parts weren't parsed correctly
Timo Sirainen <tss@iki.fi>
parents:
184
diff
changeset
|
82 parent->header_size.physical_size; |
4327b1266604
message/rfc822 mime parts weren't parsed correctly
Timo Sirainen <tss@iki.fi>
parents:
184
diff
changeset
|
83 |
0 | 84 list = &part->parent->children; |
85 while (*list != NULL) | |
86 list = &(*list)->next; | |
87 | |
88 *list = part; | |
89 return part; | |
90 } | |
91 | |
898
0d5be52d7131
Use unsigned char* when accessing non-NUL terminating strings. Compiler
Timo Sirainen <tss@iki.fi>
parents:
896
diff
changeset
|
92 static void parse_content_type(const unsigned char *value, size_t value_len, |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
93 void *context) |
0 | 94 { |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
95 struct parser_context *parser_ctx = context; |
0 | 96 const char *str; |
97 | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
98 if (parser_ctx->last_content_type != NULL || value_len == 0) |
0 | 99 return; |
100 | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
101 str = parser_ctx->last_content_type = |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
102 p_strndup(parser_ctx->pool, value, value_len); |
0 | 103 |
104 if (strcasecmp(str, "message/rfc822") == 0) | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
105 parser_ctx->part->flags |= MESSAGE_PART_FLAG_MESSAGE_RFC822; |
1662
aff92c2de6f5
"Content-Type: text" (without '/') didn't mark the message as containing
Timo Sirainen <tss@iki.fi>
parents:
1618
diff
changeset
|
106 else if (strncasecmp(str, "text", 4) == 0 && |
aff92c2de6f5
"Content-Type: text" (without '/') didn't mark the message as containing
Timo Sirainen <tss@iki.fi>
parents:
1618
diff
changeset
|
107 (str[4] == '/' || str[4] == '\0')) |
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 parser_ctx->part->flags |= MESSAGE_PART_FLAG_TEXT; |
0 | 109 else if (strncasecmp(str, "multipart/", 10) == 0) { |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
110 parser_ctx->part->flags |= MESSAGE_PART_FLAG_MULTIPART; |
0 | 111 |
106
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
112 if (strcasecmp(str+10, "digest") == 0) { |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
113 parser_ctx->part->flags |= |
106
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
114 MESSAGE_PART_FLAG_MULTIPART_DIGEST; |
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
115 } |
0 | 116 } |
117 } | |
118 | |
898
0d5be52d7131
Use unsigned char* when accessing non-NUL terminating strings. Compiler
Timo Sirainen <tss@iki.fi>
parents:
896
diff
changeset
|
119 static void |
0d5be52d7131
Use unsigned char* when accessing non-NUL terminating strings. Compiler
Timo Sirainen <tss@iki.fi>
parents:
896
diff
changeset
|
120 parse_content_type_param(const unsigned char *name, size_t name_len, |
0d5be52d7131
Use unsigned char* when accessing non-NUL terminating strings. Compiler
Timo Sirainen <tss@iki.fi>
parents:
896
diff
changeset
|
121 const unsigned char *value, size_t value_len, |
0d5be52d7131
Use unsigned char* when accessing non-NUL terminating strings. Compiler
Timo Sirainen <tss@iki.fi>
parents:
896
diff
changeset
|
122 int value_quoted, void *context) |
0 | 123 { |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
124 struct parser_context *parser_ctx = context; |
0 | 125 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
126 if ((parser_ctx->part->flags & MESSAGE_PART_FLAG_MULTIPART) == 0 || |
898
0d5be52d7131
Use unsigned char* when accessing non-NUL terminating strings. Compiler
Timo Sirainen <tss@iki.fi>
parents:
896
diff
changeset
|
127 name_len != 8 || memcasecmp(name, "boundary", 8) != 0) |
0 | 128 return; |
129 | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
130 if (parser_ctx->last_boundary == NULL) { |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
131 parser_ctx->last_boundary = |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
132 p_strndup(parser_ctx->pool, value, value_len); |
896
21ffcce83c70
Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
874
diff
changeset
|
133 if (value_quoted) |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
134 str_unescape(parser_ctx->last_boundary); |
0 | 135 } |
136 } | |
137 | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
138 static struct message_part * |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
139 message_parse_multipart(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
|
140 struct parser_context *parser_ctx) |
0 | 141 { |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
142 struct message_part *parent_part, *next_part, *part; |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
143 struct message_boundary *b; |
1534
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
144 int has_nuls; |
0 | 145 |
146 /* multipart message. add new boundary */ | |
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 b = t_new(struct message_boundary, 1); |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
148 b->part = parser_ctx->part; |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
149 b->boundary = parser_ctx->last_boundary; |
0 | 150 b->len = strlen(b->boundary); |
151 | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
152 b->next = parser_ctx->boundaries; |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
153 parser_ctx->boundaries = b; |
0 | 154 |
155 /* reset fields */ | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
156 parser_ctx->last_boundary = NULL; |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
157 parser_ctx->last_content_type = NULL; |
0 | 158 |
159 /* skip the data before the first boundary */ | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
160 parent_part = parser_ctx->part; |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
161 next_part = message_skip_boundary(input, parser_ctx->boundaries, |
1534
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
162 &parent_part->body_size, &has_nuls); |
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
163 if (has_nuls) |
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
164 parent_part->flags |= MESSAGE_PART_FLAG_HAS_NULS; |
0 | 165 |
166 /* now, parse the parts */ | |
167 while (next_part == parent_part) { | |
168 /* new child */ | |
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 part = message_part_append(parser_ctx->pool, parent_part); |
1618
149ade487f48
Ignore Content-* headers if there's no MIME-Version header. Note that this
Timo Sirainen <tss@iki.fi>
parents:
1543
diff
changeset
|
170 if ((parent_part->flags & MESSAGE_PART_FLAG_IS_MIME) != 0) |
149ade487f48
Ignore Content-* headers if there's no MIME-Version header. Note that this
Timo Sirainen <tss@iki.fi>
parents:
1543
diff
changeset
|
171 part->flags |= MESSAGE_PART_FLAG_IS_MIME; |
0 | 172 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
173 parser_ctx->part = part; |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
174 next_part = message_parse_part(input, parser_ctx); |
0 | 175 |
1534
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
176 if ((part->flags & MESSAGE_PART_FLAG_HAS_NULS) != 0) { |
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
177 /* it also belongs to parent */ |
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
178 parent_part->flags |= MESSAGE_PART_FLAG_HAS_NULS; |
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
179 } |
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
180 |
0 | 181 /* update our size */ |
182 message_size_add_part(&parent_part->body_size, part); | |
183 | |
184 if (next_part != parent_part) | |
185 break; | |
186 | |
187 /* skip the boundary */ | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
188 next_part = message_skip_boundary(input, parser_ctx->boundaries, |
1534
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
189 &parent_part->body_size, |
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
190 &has_nuls); |
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
191 if (has_nuls) |
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
192 parent_part->flags |= MESSAGE_PART_FLAG_HAS_NULS; |
0 | 193 } |
194 | |
195 /* remove boundary */ | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
196 i_assert(parser_ctx->boundaries == b); |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
197 parser_ctx->boundaries = b->next; |
0 | 198 return next_part; |
199 } | |
200 | |
874 | 201 #define MUTEX_FLAGS \ |
202 (MESSAGE_PART_FLAG_MESSAGE_RFC822 | MESSAGE_PART_FLAG_MULTIPART) | |
203 | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
204 static struct message_part * |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
205 message_parse_part(struct istream *input, struct parser_context *parser_ctx) |
0 | 206 { |
1322
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
207 struct message_header_parser_ctx *hdr_ctx; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
208 struct message_header_line *hdr; |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
209 struct message_part *next_part, *part; |
50
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
210 uoff_t hdr_size; |
1534
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
211 int has_nuls; |
0 | 212 |
1322
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
213 hdr_ctx = message_parse_header_init(input, |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
214 &parser_ctx->part->header_size); |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
215 while ((hdr = message_parse_header_next(hdr_ctx)) != NULL) { |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
216 /* call the user-defined header parser */ |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
217 if (parser_ctx->callback != NULL) { |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
218 parser_ctx->callback(parser_ctx->part, hdr, |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
219 parser_ctx->context); |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
220 } |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
221 |
1618
149ade487f48
Ignore Content-* headers if there's no MIME-Version header. Note that this
Timo Sirainen <tss@iki.fi>
parents:
1543
diff
changeset
|
222 if (!hdr->eoh && strcasecmp(hdr->name, "Mime-Version") == 0) { |
149ade487f48
Ignore Content-* headers if there's no MIME-Version header. Note that this
Timo Sirainen <tss@iki.fi>
parents:
1543
diff
changeset
|
223 /* it's MIME. Content-* headers are valid */ |
149ade487f48
Ignore Content-* headers if there's no MIME-Version header. Note that this
Timo Sirainen <tss@iki.fi>
parents:
1543
diff
changeset
|
224 parser_ctx->part->flags |= MESSAGE_PART_FLAG_IS_MIME; |
149ade487f48
Ignore Content-* headers if there's no MIME-Version header. Note that this
Timo Sirainen <tss@iki.fi>
parents:
1543
diff
changeset
|
225 } |
149ade487f48
Ignore Content-* headers if there's no MIME-Version header. Note that this
Timo Sirainen <tss@iki.fi>
parents:
1543
diff
changeset
|
226 |
1326 | 227 if (!hdr->eoh && strcasecmp(hdr->name, "Content-Type") == 0) { |
1322
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
228 if (hdr->continues) { |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
229 hdr->use_full_value = TRUE; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
230 continue; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
231 } |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
232 /* we need to know the boundary */ |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
233 message_content_parse_header(hdr->full_value, |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
234 hdr->full_value_len, |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
235 parse_content_type, |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
236 parse_content_type_param, |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
237 parser_ctx); |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
238 } |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
239 } |
1618
149ade487f48
Ignore Content-* headers if there's no MIME-Version header. Note that this
Timo Sirainen <tss@iki.fi>
parents:
1543
diff
changeset
|
240 |
149ade487f48
Ignore Content-* headers if there's no MIME-Version header. Note that this
Timo Sirainen <tss@iki.fi>
parents:
1543
diff
changeset
|
241 if ((parser_ctx->part->flags & MESSAGE_PART_FLAG_IS_MIME) == 0) { |
149ade487f48
Ignore Content-* headers if there's no MIME-Version header. Note that this
Timo Sirainen <tss@iki.fi>
parents:
1543
diff
changeset
|
242 /* It's not MIME. Reset everything we found from |
149ade487f48
Ignore Content-* headers if there's no MIME-Version header. Note that this
Timo Sirainen <tss@iki.fi>
parents:
1543
diff
changeset
|
243 Content-Type. */ |
149ade487f48
Ignore Content-* headers if there's no MIME-Version header. Note that this
Timo Sirainen <tss@iki.fi>
parents:
1543
diff
changeset
|
244 parser_ctx->part->flags = 0; |
149ade487f48
Ignore Content-* headers if there's no MIME-Version header. Note that this
Timo Sirainen <tss@iki.fi>
parents:
1543
diff
changeset
|
245 parser_ctx->last_boundary = NULL; |
149ade487f48
Ignore Content-* headers if there's no MIME-Version header. Note that this
Timo Sirainen <tss@iki.fi>
parents:
1543
diff
changeset
|
246 parser_ctx->last_content_type = NULL; |
149ade487f48
Ignore Content-* headers if there's no MIME-Version header. Note that this
Timo Sirainen <tss@iki.fi>
parents:
1543
diff
changeset
|
247 } |
1322
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
248 if (parser_ctx->callback != NULL) { |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
249 parser_ctx->callback(parser_ctx->part, NULL, |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
250 parser_ctx->context); |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
251 } |
1534
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
252 if (hdr_ctx->has_nuls) |
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
253 parser_ctx->part->flags |= MESSAGE_PART_FLAG_HAS_NULS; |
1322
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
254 message_parse_header_deinit(hdr_ctx); |
0 | 255 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
256 i_assert((parser_ctx->part->flags & MUTEX_FLAGS) != MUTEX_FLAGS); |
874 | 257 |
0 | 258 /* update message position/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
|
259 hdr_size = parser_ctx->part->header_size.physical_size; |
0 | 260 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
261 if (parser_ctx->last_boundary != NULL) |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
262 return message_parse_multipart(input, parser_ctx); |
0 | 263 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
264 if (parser_ctx->last_content_type == NULL) { |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
265 if (parser_ctx->part->parent != NULL && |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
266 (parser_ctx->part->parent->flags & |
106
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
267 MESSAGE_PART_FLAG_MULTIPART_DIGEST)) { |
0 | 268 /* when there's no content-type specified and we're |
269 below multipart/digest, the assume message/rfc822 | |
270 content-type */ | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
271 parser_ctx->part->flags |= |
106
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
272 MESSAGE_PART_FLAG_MESSAGE_RFC822; |
0 | 273 } else { |
274 /* otherwise we default to text/plain */ | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
275 parser_ctx->part->flags |= MESSAGE_PART_FLAG_TEXT; |
0 | 276 } |
277 } | |
278 | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
279 parser_ctx->last_boundary = NULL; |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
280 parser_ctx->last_content_type = NULL; |
0 | 281 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
282 if (parser_ctx->part->flags & MESSAGE_PART_FLAG_MESSAGE_RFC822) { |
0 | 283 /* message/rfc822 part - the message body begins with |
284 headers again, this works pretty much the same as | |
285 a single multipart/mixed item */ | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
286 part = message_part_append(parser_ctx->pool, parser_ctx->part); |
0 | 287 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
288 parser_ctx->part = part; |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
289 next_part = message_parse_part(input, parser_ctx); |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
290 parser_ctx->part = part->parent; |
0 | 291 |
292 /* our body size is the size of header+body in message/rfc822 */ | |
293 message_size_add_part(&part->parent->body_size, part); | |
294 } else { | |
295 /* normal message, read until the next boundary */ | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
296 part = parser_ctx->part; |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
297 next_part = message_parse_body(input, parser_ctx->boundaries, |
1534
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
298 &part->body_size, &has_nuls); |
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
299 if (has_nuls) |
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
300 part->flags |= MESSAGE_PART_FLAG_HAS_NULS; |
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
301 } |
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
302 |
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
303 if ((part->flags & MESSAGE_PART_FLAG_HAS_NULS) != 0 && |
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
304 part->parent != NULL) { |
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
305 /* it also belongs to parent */ |
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
306 part->parent->flags |= MESSAGE_PART_FLAG_HAS_NULS; |
0 | 307 } |
308 | |
309 return next_part; | |
310 } | |
311 | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
312 static void message_skip_line(struct istream *input, |
1534
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
313 struct message_size *msg_size, int skip_lf, |
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
314 int *has_nuls) |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
315 { |
410
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
369
diff
changeset
|
316 const unsigned char *msg; |
184 | 317 size_t i, size, startpos; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
318 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
319 startpos = 0; |
1534
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
320 *has_nuls = FALSE; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
321 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
322 while (i_stream_read_data(input, &msg, &size, startpos) > 0) { |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
323 for (i = startpos; i < size; i++) { |
1534
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
324 if (msg[i] == '\0') |
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
325 *has_nuls = TRUE; |
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
326 else if (msg[i] == '\n') { |
1253
39b899338c99
A few small fixes to MIME and mail address parsers.
Timo Sirainen <tss@iki.fi>
parents:
1061
diff
changeset
|
327 if (!skip_lf) { |
39b899338c99
A few small fixes to MIME and mail address parsers.
Timo Sirainen <tss@iki.fi>
parents:
1061
diff
changeset
|
328 if (i > 0 && msg[i-1] == '\r') |
39b899338c99
A few small fixes to MIME and mail address parsers.
Timo Sirainen <tss@iki.fi>
parents:
1061
diff
changeset
|
329 i--; |
39b899338c99
A few small fixes to MIME and mail address parsers.
Timo Sirainen <tss@iki.fi>
parents:
1061
diff
changeset
|
330 startpos = i; |
39b899338c99
A few small fixes to MIME and mail address parsers.
Timo Sirainen <tss@iki.fi>
parents:
1061
diff
changeset
|
331 goto __break; |
39b899338c99
A few small fixes to MIME and mail address parsers.
Timo Sirainen <tss@iki.fi>
parents:
1061
diff
changeset
|
332 } |
39b899338c99
A few small fixes to MIME and mail address parsers.
Timo Sirainen <tss@iki.fi>
parents:
1061
diff
changeset
|
333 |
153
9660df1ca44f
message_parse_header() was buggy with big headers, and io_buffer_read_data()
Timo Sirainen <tss@iki.fi>
parents:
112
diff
changeset
|
334 if (msg_size != NULL) { |
9660df1ca44f
message_parse_header() was buggy with big headers, and io_buffer_read_data()
Timo Sirainen <tss@iki.fi>
parents:
112
diff
changeset
|
335 if (i == 0 || msg[i-1] != '\r') |
9660df1ca44f
message_parse_header() was buggy with big headers, and io_buffer_read_data()
Timo Sirainen <tss@iki.fi>
parents:
112
diff
changeset
|
336 msg_size->virtual_size++; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
337 msg_size->lines++; |
153
9660df1ca44f
message_parse_header() was buggy with big headers, and io_buffer_read_data()
Timo Sirainen <tss@iki.fi>
parents:
112
diff
changeset
|
338 } |
1253
39b899338c99
A few small fixes to MIME and mail address parsers.
Timo Sirainen <tss@iki.fi>
parents:
1061
diff
changeset
|
339 startpos = i+1; |
39b899338c99
A few small fixes to MIME and mail address parsers.
Timo Sirainen <tss@iki.fi>
parents:
1061
diff
changeset
|
340 goto __break; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
341 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
342 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
343 |
232
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
344 /* leave the last character, it may be \r */ |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
345 i_stream_skip(input, i - 1); |
232
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
346 startpos = 1; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
347 |
232
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
348 if (msg_size != NULL) { |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
349 msg_size->physical_size += i - 1; |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
350 msg_size->virtual_size += i - 1; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
351 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
352 } |
1253
39b899338c99
A few small fixes to MIME and mail address parsers.
Timo Sirainen <tss@iki.fi>
parents:
1061
diff
changeset
|
353 __break: |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
354 i_stream_skip(input, startpos); |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
355 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
356 if (msg_size != NULL) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
357 msg_size->physical_size += startpos; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
358 msg_size->virtual_size += startpos; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
359 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
360 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
361 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
362 static struct message_boundary * |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
363 boundary_find(struct message_boundary *boundaries, |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
364 const unsigned char *msg, size_t len) |
0 | 365 { |
366 while (boundaries != NULL) { | |
367 if (boundaries->len <= len && | |
898
0d5be52d7131
Use unsigned char* when accessing non-NUL terminating strings. Compiler
Timo Sirainen <tss@iki.fi>
parents:
896
diff
changeset
|
368 memcmp(boundaries->boundary, msg, boundaries->len) == 0) |
0 | 369 return boundaries; |
370 | |
371 boundaries = boundaries->next; | |
372 } | |
373 | |
374 return NULL; | |
375 } | |
376 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
377 /* read until next boundary is found. if skip_over = FALSE, stop at the |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
378 [\r]\n before the boundary, otherwise leave it right after the known |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
379 boundary so the ending "--" can be checked. */ |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
380 static struct message_boundary * |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
381 message_find_boundary(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
|
382 struct message_boundary *boundaries, |
1534
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
383 struct message_size *msg_size, int skip_over, |
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
384 int *has_nuls) |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
385 { |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
386 struct message_boundary *boundary; |
410
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
369
diff
changeset
|
387 const unsigned char *msg; |
184 | 388 size_t i, size, startpos, line_start, missing_cr_count; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
389 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
390 boundary = NULL; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
391 missing_cr_count = startpos = line_start = 0; |
1534
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
392 *has_nuls = FALSE; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
393 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
394 while (i_stream_read_data(input, &msg, &size, startpos) > 0) { |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
395 for (i = startpos; i < size; i++) { |
1534
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
396 if (msg[i] != '\n') { |
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
397 if (msg[i] == '\0') |
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
398 *has_nuls = TRUE; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
399 continue; |
1534
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
400 } |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
401 |
1413
f9f69a6fdd63
We stopped parsing message if there was a line longer than input buffer
Timo Sirainen <tss@iki.fi>
parents:
1326
diff
changeset
|
402 if (line_start != (size_t)-1 && |
f9f69a6fdd63
We stopped parsing message if there was a line longer than input buffer
Timo Sirainen <tss@iki.fi>
parents:
1326
diff
changeset
|
403 i >= line_start+2 && msg[line_start] == '-' && |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
404 msg[line_start+1] == '-') { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
405 /* possible boundary */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
406 boundary = boundary_find(boundaries, |
898
0d5be52d7131
Use unsigned char* when accessing non-NUL terminating strings. Compiler
Timo Sirainen <tss@iki.fi>
parents:
896
diff
changeset
|
407 msg + line_start + 2, |
0d5be52d7131
Use unsigned char* when accessing non-NUL terminating strings. Compiler
Timo Sirainen <tss@iki.fi>
parents:
896
diff
changeset
|
408 i - line_start - 2); |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
409 if (boundary != NULL) |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
410 break; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
411 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
412 |
9
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
7
diff
changeset
|
413 if (i == 0 || msg[i-1] != '\r') { |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
414 /* missing CR */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
415 missing_cr_count++; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
416 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
417 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
418 msg_size->lines++; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
419 line_start = i+1; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
420 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
421 |
232
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
422 if (boundary != NULL) |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
423 break; |
232
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
424 |
1413
f9f69a6fdd63
We stopped parsing message if there was a line longer than input buffer
Timo Sirainen <tss@iki.fi>
parents:
1326
diff
changeset
|
425 if (line_start == (size_t)-1) { |
f9f69a6fdd63
We stopped parsing message if there was a line longer than input buffer
Timo Sirainen <tss@iki.fi>
parents:
1326
diff
changeset
|
426 /* continued long line, continue skipping over it */ |
f9f69a6fdd63
We stopped parsing message if there was a line longer than input buffer
Timo Sirainen <tss@iki.fi>
parents:
1326
diff
changeset
|
427 } else if (i - line_start > 128) { |
232
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
428 /* long partial line, see if it's a boundary. |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
429 RFC-2046 says that the boundaries must be |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
430 70 chars without "--" or less. We allow |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
431 a bit larger.. */ |
1413
f9f69a6fdd63
We stopped parsing message if there was a line longer than input buffer
Timo Sirainen <tss@iki.fi>
parents:
1326
diff
changeset
|
432 if (msg[line_start] == '-' && |
f9f69a6fdd63
We stopped parsing message if there was a line longer than input buffer
Timo Sirainen <tss@iki.fi>
parents:
1326
diff
changeset
|
433 msg[line_start+1] == '-') { |
f9f69a6fdd63
We stopped parsing message if there was a line longer than input buffer
Timo Sirainen <tss@iki.fi>
parents:
1326
diff
changeset
|
434 boundary = boundary_find(boundaries, |
f9f69a6fdd63
We stopped parsing message if there was a line longer than input buffer
Timo Sirainen <tss@iki.fi>
parents:
1326
diff
changeset
|
435 msg + line_start + 2, |
f9f69a6fdd63
We stopped parsing message if there was a line longer than input buffer
Timo Sirainen <tss@iki.fi>
parents:
1326
diff
changeset
|
436 i - line_start - 2); |
f9f69a6fdd63
We stopped parsing message if there was a line longer than input buffer
Timo Sirainen <tss@iki.fi>
parents:
1326
diff
changeset
|
437 if (boundary != NULL) |
f9f69a6fdd63
We stopped parsing message if there was a line longer than input buffer
Timo Sirainen <tss@iki.fi>
parents:
1326
diff
changeset
|
438 break; |
f9f69a6fdd63
We stopped parsing message if there was a line longer than input buffer
Timo Sirainen <tss@iki.fi>
parents:
1326
diff
changeset
|
439 } |
232
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
440 |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
441 /* nope, we can skip over the line, just |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
442 leave the last char since it may be \r */ |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
443 i--; |
1413
f9f69a6fdd63
We stopped parsing message if there was a line longer than input buffer
Timo Sirainen <tss@iki.fi>
parents:
1326
diff
changeset
|
444 line_start = (size_t)-1; |
232
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
445 } else { |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
446 /* leave the last line to buffer, it may be |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
447 boundary */ |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
448 i = line_start; |
1253
39b899338c99
A few small fixes to MIME and mail address parsers.
Timo Sirainen <tss@iki.fi>
parents:
1061
diff
changeset
|
449 if (i > 0) i--; /* leave the \r\n too */ |
39b899338c99
A few small fixes to MIME and mail address parsers.
Timo Sirainen <tss@iki.fi>
parents:
1061
diff
changeset
|
450 if (i > 0) i--; |
232
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
451 line_start -= i; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
452 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
453 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
454 i_stream_skip(input, i); |
232
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
455 msg_size->physical_size += i; |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
456 msg_size->virtual_size += i; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
457 |
232
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
458 startpos = size - i; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
459 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
460 |
1413
f9f69a6fdd63
We stopped parsing message if there was a line longer than input buffer
Timo Sirainen <tss@iki.fi>
parents:
1326
diff
changeset
|
461 if (boundary == NULL && |
f9f69a6fdd63
We stopped parsing message if there was a line longer than input buffer
Timo Sirainen <tss@iki.fi>
parents:
1326
diff
changeset
|
462 line_start != (size_t)-1 && line_start+2 <= size && |
1253
39b899338c99
A few small fixes to MIME and mail address parsers.
Timo Sirainen <tss@iki.fi>
parents:
1061
diff
changeset
|
463 msg[line_start] == '-' && msg[line_start+1] == '-') { |
39b899338c99
A few small fixes to MIME and mail address parsers.
Timo Sirainen <tss@iki.fi>
parents:
1061
diff
changeset
|
464 /* possible boundary without line feed at end */ |
39b899338c99
A few small fixes to MIME and mail address parsers.
Timo Sirainen <tss@iki.fi>
parents:
1061
diff
changeset
|
465 boundary = boundary_find(boundaries, |
39b899338c99
A few small fixes to MIME and mail address parsers.
Timo Sirainen <tss@iki.fi>
parents:
1061
diff
changeset
|
466 msg + line_start + 2, |
39b899338c99
A few small fixes to MIME and mail address parsers.
Timo Sirainen <tss@iki.fi>
parents:
1061
diff
changeset
|
467 size - line_start - 2); |
39b899338c99
A few small fixes to MIME and mail address parsers.
Timo Sirainen <tss@iki.fi>
parents:
1061
diff
changeset
|
468 } |
39b899338c99
A few small fixes to MIME and mail address parsers.
Timo Sirainen <tss@iki.fi>
parents:
1061
diff
changeset
|
469 |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
470 if (boundary != NULL) { |
1413
f9f69a6fdd63
We stopped parsing message if there was a line longer than input buffer
Timo Sirainen <tss@iki.fi>
parents:
1326
diff
changeset
|
471 i_assert(line_start != (size_t)-1); |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
472 if (skip_over) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
473 /* leave the pointer right after the boundary */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
474 line_start += 2 + boundary->len; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
475 } else if (line_start > 0 && msg[line_start-1] == '\n') { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
476 /* leave the \r\n before the boundary */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
477 line_start--; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
478 msg_size->lines--; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
479 |
9
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
7
diff
changeset
|
480 if (line_start > 0 && msg[line_start-1] == '\r') |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
481 line_start--; |
9
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
7
diff
changeset
|
482 else |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
483 missing_cr_count--; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
484 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
485 startpos = line_start; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
486 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
487 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
488 i_stream_skip(input, startpos); |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
489 msg_size->physical_size += startpos; |
9
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
7
diff
changeset
|
490 msg_size->virtual_size += startpos + missing_cr_count; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
491 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
492 i_assert(msg_size->virtual_size >= msg_size->physical_size); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
493 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
494 return boundary; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
495 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
496 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
497 static struct message_part * |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
498 message_parse_body(struct istream *input, struct message_boundary *boundaries, |
1534
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
499 struct message_size *msg_size, int *has_nuls) |
0 | 500 { |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
501 struct message_boundary *boundary; |
1253
39b899338c99
A few small fixes to MIME and mail address parsers.
Timo Sirainen <tss@iki.fi>
parents:
1061
diff
changeset
|
502 struct message_size body_size; |
0 | 503 |
9
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
7
diff
changeset
|
504 if (boundaries == NULL) { |
1543
7ac153f21949
Removed useless parameters from message_get_body_size(). Also did some small
Timo Sirainen <tss@iki.fi>
parents:
1534
diff
changeset
|
505 message_get_body_size(input, &body_size, has_nuls); |
1253
39b899338c99
A few small fixes to MIME and mail address parsers.
Timo Sirainen <tss@iki.fi>
parents:
1061
diff
changeset
|
506 message_size_add(msg_size, &body_size); |
1534
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
507 boundary = NULL; |
9
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
7
diff
changeset
|
508 } else { |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
509 boundary = message_find_boundary(input, boundaries, |
1534
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
510 msg_size, FALSE, has_nuls); |
9
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
7
diff
changeset
|
511 } |
1534
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
512 |
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
513 return boundary == NULL ? NULL : boundary->part; |
0 | 514 } |
515 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
516 /* skip data until next boundary is found. if it's end boundary, |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
517 skip the footer as well. */ |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
518 static struct message_part * |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
519 message_skip_boundary(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
|
520 struct message_boundary *boundaries, |
1534
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
521 struct message_size *boundary_size, int *has_nuls) |
0 | 522 { |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
523 struct message_boundary *boundary; |
410
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
369
diff
changeset
|
524 const unsigned char *msg; |
184 | 525 size_t size; |
0 | 526 int end_boundary; |
527 | |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
528 boundary = message_find_boundary(input, boundaries, |
1534
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
529 boundary_size, TRUE, has_nuls); |
0 | 530 if (boundary == NULL) |
531 return NULL; | |
532 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
533 /* now, see if it's end boundary */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
534 end_boundary = FALSE; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
535 if (i_stream_read_data(input, &msg, &size, 1) > 0) |
232
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
536 end_boundary = msg[0] == '-' && msg[1] == '-'; |
0 | 537 |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
538 /* skip the rest of the line */ |
1534
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
539 message_skip_line(input, boundary_size, !end_boundary, has_nuls); |
0 | 540 |
541 if (end_boundary) { | |
542 /* skip the footer */ | |
1534
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
543 return message_parse_body(input, boundary->next, |
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
544 boundary_size, has_nuls); |
0 | 545 } |
546 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
547 return boundary == NULL ? NULL : boundary->part; |
0 | 548 } |
1322
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
549 |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
550 struct message_part *message_parse(pool_t pool, struct istream *input, |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
551 message_header_callback_t *callback, |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
552 void *context) |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
553 { |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
554 struct message_part *part; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
555 struct parser_context parser_ctx; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
556 |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
557 memset(&parser_ctx, 0, sizeof(parser_ctx)); |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
558 parser_ctx.pool = pool; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
559 parser_ctx.callback = callback; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
560 parser_ctx.context = context; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
561 parser_ctx.part = part = p_new(pool, struct message_part, 1); |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
562 |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
563 message_parse_part(input, &parser_ctx); |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
564 return part; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
565 } |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
566 |
1689
c07b98265577
If BODY/BODYSTRUCTURE is requested with some other headers, parse the
Timo Sirainen <tss@iki.fi>
parents:
1662
diff
changeset
|
567 static void part_parse_headers(struct message_part *part, struct istream *input, |
c07b98265577
If BODY/BODYSTRUCTURE is requested with some other headers, parse the
Timo Sirainen <tss@iki.fi>
parents:
1662
diff
changeset
|
568 uoff_t start_offset, |
c07b98265577
If BODY/BODYSTRUCTURE is requested with some other headers, parse the
Timo Sirainen <tss@iki.fi>
parents:
1662
diff
changeset
|
569 message_header_callback_t *callback, |
c07b98265577
If BODY/BODYSTRUCTURE is requested with some other headers, parse the
Timo Sirainen <tss@iki.fi>
parents:
1662
diff
changeset
|
570 void *context) |
c07b98265577
If BODY/BODYSTRUCTURE is requested with some other headers, parse the
Timo Sirainen <tss@iki.fi>
parents:
1662
diff
changeset
|
571 { |
c07b98265577
If BODY/BODYSTRUCTURE is requested with some other headers, parse the
Timo Sirainen <tss@iki.fi>
parents:
1662
diff
changeset
|
572 while (part != NULL) { |
c07b98265577
If BODY/BODYSTRUCTURE is requested with some other headers, parse the
Timo Sirainen <tss@iki.fi>
parents:
1662
diff
changeset
|
573 /* note that we want to parse the header of all |
c07b98265577
If BODY/BODYSTRUCTURE is requested with some other headers, parse the
Timo Sirainen <tss@iki.fi>
parents:
1662
diff
changeset
|
574 the message parts, multiparts too. */ |
c07b98265577
If BODY/BODYSTRUCTURE is requested with some other headers, parse the
Timo Sirainen <tss@iki.fi>
parents:
1662
diff
changeset
|
575 i_assert(part->physical_pos >= input->v_offset - start_offset); |
c07b98265577
If BODY/BODYSTRUCTURE is requested with some other headers, parse the
Timo Sirainen <tss@iki.fi>
parents:
1662
diff
changeset
|
576 i_stream_skip(input, part->physical_pos - |
c07b98265577
If BODY/BODYSTRUCTURE is requested with some other headers, parse the
Timo Sirainen <tss@iki.fi>
parents:
1662
diff
changeset
|
577 (input->v_offset - start_offset)); |
c07b98265577
If BODY/BODYSTRUCTURE is requested with some other headers, parse the
Timo Sirainen <tss@iki.fi>
parents:
1662
diff
changeset
|
578 |
c07b98265577
If BODY/BODYSTRUCTURE is requested with some other headers, parse the
Timo Sirainen <tss@iki.fi>
parents:
1662
diff
changeset
|
579 message_parse_header(part, input, NULL, callback, context); |
c07b98265577
If BODY/BODYSTRUCTURE is requested with some other headers, parse the
Timo Sirainen <tss@iki.fi>
parents:
1662
diff
changeset
|
580 if (part->children != NULL) { |
c07b98265577
If BODY/BODYSTRUCTURE is requested with some other headers, parse the
Timo Sirainen <tss@iki.fi>
parents:
1662
diff
changeset
|
581 part_parse_headers(part->children, input, |
c07b98265577
If BODY/BODYSTRUCTURE is requested with some other headers, parse the
Timo Sirainen <tss@iki.fi>
parents:
1662
diff
changeset
|
582 start_offset, callback, context); |
c07b98265577
If BODY/BODYSTRUCTURE is requested with some other headers, parse the
Timo Sirainen <tss@iki.fi>
parents:
1662
diff
changeset
|
583 } |
c07b98265577
If BODY/BODYSTRUCTURE is requested with some other headers, parse the
Timo Sirainen <tss@iki.fi>
parents:
1662
diff
changeset
|
584 |
c07b98265577
If BODY/BODYSTRUCTURE is requested with some other headers, parse the
Timo Sirainen <tss@iki.fi>
parents:
1662
diff
changeset
|
585 part = part->next; |
c07b98265577
If BODY/BODYSTRUCTURE is requested with some other headers, parse the
Timo Sirainen <tss@iki.fi>
parents:
1662
diff
changeset
|
586 } |
c07b98265577
If BODY/BODYSTRUCTURE is requested with some other headers, parse the
Timo Sirainen <tss@iki.fi>
parents:
1662
diff
changeset
|
587 } |
c07b98265577
If BODY/BODYSTRUCTURE is requested with some other headers, parse the
Timo Sirainen <tss@iki.fi>
parents:
1662
diff
changeset
|
588 |
c07b98265577
If BODY/BODYSTRUCTURE is requested with some other headers, parse the
Timo Sirainen <tss@iki.fi>
parents:
1662
diff
changeset
|
589 void message_parse_from_parts(struct message_part *part, struct istream *input, |
c07b98265577
If BODY/BODYSTRUCTURE is requested with some other headers, parse the
Timo Sirainen <tss@iki.fi>
parents:
1662
diff
changeset
|
590 message_header_callback_t *callback, |
c07b98265577
If BODY/BODYSTRUCTURE is requested with some other headers, parse the
Timo Sirainen <tss@iki.fi>
parents:
1662
diff
changeset
|
591 void *context) |
c07b98265577
If BODY/BODYSTRUCTURE is requested with some other headers, parse the
Timo Sirainen <tss@iki.fi>
parents:
1662
diff
changeset
|
592 { |
c07b98265577
If BODY/BODYSTRUCTURE is requested with some other headers, parse the
Timo Sirainen <tss@iki.fi>
parents:
1662
diff
changeset
|
593 part_parse_headers(part, input, input->v_offset, callback, context); |
c07b98265577
If BODY/BODYSTRUCTURE is requested with some other headers, parse the
Timo Sirainen <tss@iki.fi>
parents:
1662
diff
changeset
|
594 } |
c07b98265577
If BODY/BODYSTRUCTURE is requested with some other headers, parse the
Timo Sirainen <tss@iki.fi>
parents:
1662
diff
changeset
|
595 |
1322
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
596 void message_parse_header(struct message_part *part, struct istream *input, |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
597 struct message_size *hdr_size, |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
598 message_header_callback_t *callback, void *context) |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
599 { |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
600 struct message_header_parser_ctx *hdr_ctx; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
601 struct message_header_line *hdr; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
602 |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
603 hdr_ctx = message_parse_header_init(input, hdr_size); |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
604 while ((hdr = message_parse_header_next(hdr_ctx)) != NULL) |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
605 callback(part, hdr, context); |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
606 callback(part, NULL, context); |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
607 message_parse_header_deinit(hdr_ctx); |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
608 } |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
609 |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
610 struct message_header_parser_ctx * |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
611 message_parse_header_init(struct istream *input, struct message_size *hdr_size) |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
612 { |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
613 struct message_header_parser_ctx *ctx; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
614 |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
615 ctx = i_new(struct message_header_parser_ctx, 1); |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
616 ctx->input = input; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
617 ctx->hdr_size = hdr_size; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
618 ctx->name = str_new(default_pool, 128); |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
619 |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
620 if (hdr_size != NULL) |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
621 memset(hdr_size, 0, sizeof(*hdr_size)); |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
622 return ctx; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
623 } |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
624 |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
625 void message_parse_header_deinit(struct message_header_parser_ctx *ctx) |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
626 { |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
627 i_stream_skip(ctx->input, ctx->skip); |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
628 if (ctx->value_buf != NULL) |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
629 buffer_free(ctx->value_buf); |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
630 str_free(ctx->name); |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
631 i_free(ctx); |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
632 } |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
633 |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
634 struct message_header_line * |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
635 message_parse_header_next(struct message_header_parser_ctx *ctx) |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
636 { |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
637 struct message_header_line *line = &ctx->line; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
638 const unsigned char *msg; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
639 size_t i, size, startpos, colon_pos, parse_size; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
640 int ret; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
641 |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
642 if (line->eoh) |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
643 return NULL; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
644 |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
645 if (ctx->skip > 0) { |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
646 i_stream_skip(ctx->input, ctx->skip); |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
647 ctx->skip = 0; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
648 } |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
649 |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
650 startpos = 0; colon_pos = UINT_MAX; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
651 |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
652 line->no_newline = FALSE; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
653 |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
654 if (line->continues) { |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
655 if (line->use_full_value && !line->continued) { |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
656 /* save the first line */ |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
657 if (ctx->value_buf != NULL) |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
658 buffer_set_used_size(ctx->value_buf, 0); |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
659 else { |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
660 ctx->value_buf = |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
661 buffer_create_dynamic(default_pool, |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
662 4096, (size_t)-1); |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
663 } |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
664 buffer_append(ctx->value_buf, |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
665 line->value, line->value_len); |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
666 } |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
667 |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
668 line->continued = TRUE; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
669 line->continues = FALSE; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
670 colon_pos = 0; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
671 } else { |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
672 /* new header line */ |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
673 line->continued = FALSE; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
674 } |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
675 |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
676 for (;;) { |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
677 ret = i_stream_read_data(ctx->input, &msg, &size, startpos+1); |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
678 |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
679 if (ret != 0) { |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
680 /* we want to know one byte in advance to find out |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
681 if it's multiline header */ |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
682 parse_size = size-1; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
683 } else { |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
684 parse_size = size; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
685 } |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
686 |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
687 if (ret <= 0 && (ret != 0 || startpos == size)) { |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
688 if (ret == -1) { |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
689 /* error / EOF with no bytes */ |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
690 return NULL; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
691 } |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
692 |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
693 /* a) line is larger than input buffer |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
694 b) header ended unexpectedly */ |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
695 if (colon_pos == UINT_MAX) { |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
696 /* header name is huge. just skip it. */ |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
697 message_skip_line(ctx->input, ctx->hdr_size, |
1534
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
698 TRUE, &ctx->has_nuls); |
1322
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
699 continue; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
700 } |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
701 |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
702 /* go back to last LWSP if found. */ |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
703 for (i = size-1; i > colon_pos; i--) { |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
704 if (IS_LWSP(msg[i])) { |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
705 size = i; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
706 break; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
707 } |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
708 } |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
709 |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
710 line->no_newline = TRUE; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
711 line->continues = TRUE; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
712 ctx->skip = size; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
713 break; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
714 } |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
715 |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
716 /* find ':' */ |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
717 if (colon_pos == UINT_MAX) { |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
718 for (i = startpos; i < parse_size; i++) { |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
719 if (msg[i] <= ':') { |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
720 if (msg[i] == ':') { |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
721 colon_pos = i; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
722 break; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
723 } |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
724 if (msg[i] == '\n') { |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
725 /* end of headers, or error */ |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
726 break; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
727 } |
1534
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
728 |
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
729 if (msg[i] == '\0') |
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
730 ctx->has_nuls = TRUE; |
1322
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
731 } |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
732 } |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
733 } |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
734 |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
735 /* find '\n' */ |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
736 for (i = startpos; i < parse_size; i++) { |
1534
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
737 if (msg[i] <= '\n') { |
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
738 if (msg[i] == '\n') |
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
739 break; |
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
740 if (msg[i] == '\0') |
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
741 ctx->has_nuls = TRUE; |
676995d7c0ca
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
Timo Sirainen <tss@iki.fi>
parents:
1532
diff
changeset
|
742 } |
1322
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
743 } |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
744 |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
745 if (i < parse_size) { |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
746 /* got a line */ |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
747 line->continues = i+1 < size && IS_LWSP(msg[i+1]); |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
748 |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
749 if (ctx->hdr_size != NULL) |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
750 ctx->hdr_size->lines++; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
751 if (i == 0 || msg[i-1] != '\r') { |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
752 /* missing CR */ |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
753 if (ctx->hdr_size != NULL) |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
754 ctx->hdr_size->virtual_size++; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
755 size = i; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
756 } else { |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
757 size = i-1; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
758 } |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
759 |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
760 ctx->skip = i+1; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
761 break; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
762 } |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
763 |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
764 startpos = i; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
765 } |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
766 |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
767 if (size == 0 || (size == 1 && msg[0] == '\r')) { |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
768 /* end of headers */ |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
769 line->eoh = TRUE; |
1495
4d358048e9d7
Reset line->name and full_value* fields at end of headers. Envelope parser
Timo Sirainen <tss@iki.fi>
parents:
1413
diff
changeset
|
770 line->name_len = line->value_len = line->full_value_len = 0; |
4d358048e9d7
Reset line->name and full_value* fields at end of headers. Envelope parser
Timo Sirainen <tss@iki.fi>
parents:
1413
diff
changeset
|
771 line->name = ""; line->value = line->full_value = NULL; |
1322
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
772 } else if (line->continued) { |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
773 line->value = msg; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
774 line->value_len = size; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
775 } else if (colon_pos == UINT_MAX) { |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
776 /* missing ':', assume the whole line is name */ |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
777 line->value = NULL; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
778 line->value_len = 0; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
779 |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
780 str_truncate(ctx->name, 0); |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
781 str_append_n(ctx->name, msg, size); |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
782 line->name = str_c(ctx->name); |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
783 line->name_len = str_len(ctx->name); |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
784 } else { |
1532
d15bfc7cae1c
message_parse_header(): skip all LWSP after ':' or in continued header. It's
Timo Sirainen <tss@iki.fi>
parents:
1495
diff
changeset
|
785 /* get value. skip all LWSP after ':'. Note that RFC2822 |
d15bfc7cae1c
message_parse_header(): skip all LWSP after ':' or in continued header. It's
Timo Sirainen <tss@iki.fi>
parents:
1495
diff
changeset
|
786 doesn't say we should, but history behind it.. */ |
1322
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
787 line->value = msg + colon_pos+1; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
788 line->value_len = size - colon_pos - 1; |
1532
d15bfc7cae1c
message_parse_header(): skip all LWSP after ':' or in continued header. It's
Timo Sirainen <tss@iki.fi>
parents:
1495
diff
changeset
|
789 while (line->value_len > 0 && |
d15bfc7cae1c
message_parse_header(): skip all LWSP after ':' or in continued header. It's
Timo Sirainen <tss@iki.fi>
parents:
1495
diff
changeset
|
790 IS_LWSP(line->value[0])) { |
1322
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
791 line->value++; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
792 line->value_len--; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
793 } |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
794 |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
795 /* get name, skip LWSP before ':' */ |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
796 while (colon_pos > 0 && IS_LWSP(msg[colon_pos-1])) |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
797 colon_pos--; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
798 |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
799 str_truncate(ctx->name, 0); |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
800 str_append_n(ctx->name, msg, colon_pos); |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
801 line->name = str_c(ctx->name); |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
802 line->name_len = str_len(ctx->name); |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
803 } |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
804 |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
805 if (!line->continued) { |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
806 /* first header line, set full_value = value */ |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
807 line->full_value = line->value; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
808 line->full_value_len = line->value_len; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
809 } else if (line->use_full_value) { |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
810 /* continue saving the full value */ |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
811 buffer_append(ctx->value_buf, line->value, line->value_len); |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
812 line->full_value = buffer_get_data(ctx->value_buf, |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
813 &line->full_value_len); |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
814 } else { |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
815 /* we didn't want full_value, and this is a continued line. */ |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
816 line->full_value = NULL; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
817 line->full_value_len = 0; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
818 } |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
819 |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
820 /* always reset it */ |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
821 line->use_full_value = FALSE; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
822 |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
823 if (ctx->hdr_size != NULL) { |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
824 ctx->hdr_size->physical_size += ctx->skip; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
825 ctx->hdr_size->virtual_size += ctx->skip; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
826 } |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
827 return line; |
97f8c00b8d4c
Better handling for multiline headers. Before we skipped headers larger than
Timo Sirainen <tss@iki.fi>
parents:
1253
diff
changeset
|
828 } |