[dovecot-cvs] dovecot/src/lib-imap imap-bodystructure.c,1.32,1.33 imap-envelope.c,1.24,1.25 imap-envelope.h,1.9,1.10 imap-quote.c,1.10,1.11
cras at procontrol.fi
cras at procontrol.fi
Wed Mar 26 19:29:04 EET 2003
Update of /home/cvs/dovecot/src/lib-imap
In directory danu:/tmp/cvs-serv10853/lib-imap
Modified Files:
imap-bodystructure.c imap-envelope.c imap-envelope.h
imap-quote.c
Log Message:
Better handling for multiline headers. Before we skipped headers larger than
input buffer size (8k with read (default), 256k with mmap). The skipping was
also a bit buggy.
Now we parse the lines one at a time. There's also a way to read the header
fully into memory before parsing it, if really needed.
Index: imap-bodystructure.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-imap/imap-bodystructure.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -d -r1.32 -r1.33
--- imap-bodystructure.c 25 Feb 2003 21:05:52 -0000 1.32
+++ imap-bodystructure.c 26 Mar 2003 17:29:02 -0000 1.33
@@ -1,6 +1,7 @@
/* Copyright (C) 2002 Timo Sirainen */
#include "lib.h"
+#include "buffer.h"
#include "istream.h"
#include "str.h"
#include "message-parser.h"
@@ -141,99 +142,114 @@
message_tokenize_deinit(tok);
}
-static void parse_header(struct message_part *part,
- const unsigned char *name, size_t name_len,
- const unsigned char *value, size_t value_len,
- void *context)
+static void parse_content_header(struct message_part_body_data *d,
+ struct message_header_line *hdr,
+ pool_t pool)
{
- pool_t pool = context;
- struct message_part_body_data *part_data;
- int parent_rfc822;
+ const char *name = hdr->name;
+ const unsigned char *value;
+ size_t value_len;
- parent_rfc822 = part->parent != NULL &&
- (part->parent->flags & MESSAGE_PART_FLAG_MESSAGE_RFC822);
- if (!parent_rfc822 && (name_len <= 8 ||
- memcasecmp(name, "Content-", 8) != 0))
+ if (strncasecmp(name, "Content-", 8) != 0)
return;
+ name += 8;
- if (part->context == NULL) {
- /* initialize message part data */
- part->context = part_data =
- p_new(pool, struct message_part_body_data, 1);
- part_data->pool = pool;
+ if (hdr->continues) {
+ hdr->use_full_value = TRUE;
+ return;
}
- part_data = part->context;
- t_push();
+ value = hdr->full_value;
+ value_len = hdr->full_value_len;
- switch (name_len) {
- case 10:
- if (memcasecmp(name, "Content-ID", 10) == 0 &&
- part_data->content_id == NULL) {
- part_data->content_id =
- imap_quote(pool, value, value_len);
- }
+ switch (*name) {
+ case 'i':
+ case 'I':
+ if (strcasecmp(name, "ID") == 0 && d->content_id == NULL)
+ d->content_id = imap_quote(pool, value, value_len);
break;
- case 11:
- if (memcasecmp(name, "Content-MD5", 11) == 0 &&
- part_data->content_md5 == NULL) {
- part_data->content_md5 =
- imap_quote(pool, value, value_len);
- }
+ case 'm':
+ case 'M':
+ if (strcasecmp(name, "MD5") == 0 && d->content_md5 == NULL)
+ d->content_md5 = imap_quote(pool, value, value_len);
break;
- case 12:
- if (memcasecmp(name, "Content-Type", 12) != 0 ||
- part_data->content_type != NULL)
- break;
-
- part_data->str = t_str_new(256);
- message_content_parse_header(value, value_len,
- parse_content_type,
- parse_save_params_list, part_data);
- part_data->content_type_params =
- p_strdup_empty(pool, str_c(part_data->str));
+ case 't':
+ case 'T':
+ if (strcasecmp(name, "Type") == 0 && d->content_type == NULL) {
+ d->str = t_str_new(256);
+ message_content_parse_header(value, value_len,
+ parse_content_type,
+ parse_save_params_list, d);
+ d->content_type_params =
+ p_strdup_empty(pool, str_c(d->str));
+ }
+ if (strcasecmp(name, "Transfer-Encoding") == 0 &&
+ d->content_transfer_encoding == NULL) {
+ message_content_parse_header(value, value_len,
+ parse_content_transfer_encoding,
+ NULL, d);
+ }
break;
- case 16:
- if (memcasecmp(name, "Content-Language", 16) == 0)
- parse_content_language(value, value_len, part_data);
+ case 'l':
+ case 'L':
+ if (strcasecmp(name, "Language") == 0 &&
+ d->content_language == NULL)
+ parse_content_language(value, value_len, d);
break;
- case 19:
- if (memcasecmp(name, "Content-Description", 19) == 0 &&
- part_data->content_description == NULL) {
- part_data->content_description =
+ case 'd':
+ case 'D':
+ if (strcasecmp(name, "Description") == 0 &&
+ d->content_description == NULL) {
+ d->content_description =
imap_quote(pool, value, value_len);
}
- if (memcasecmp(name, "Content-Disposition", 19) == 0 &&
- part_data->content_disposition_params == NULL) {
- part_data->str = t_str_new(256);
+ if (strcasecmp(name, "Disposition") == 0 &&
+ d->content_disposition_params == NULL) {
+ d->str = t_str_new(256);
message_content_parse_header(value, value_len,
parse_content_disposition,
- parse_save_params_list,
- part_data);
- part_data->content_disposition_params =
- p_strdup_empty(pool, str_c(part_data->str));
+ parse_save_params_list, d);
+ d->content_disposition_params =
+ p_strdup_empty(pool, str_c(d->str));
}
break;
+ }
+}
- case 25:
- if (memcasecmp(name, "Content-Transfer-Encoding", 25) != 0 ||
- part_data->content_transfer_encoding != NULL)
- break;
+static void parse_header(struct message_part *part,
+ struct message_header_line *hdr, void *context)
+{
+ pool_t pool = context;
+ struct message_part_body_data *part_data;
+ int parent_rfc822;
- message_content_parse_header(value, value_len,
- parse_content_transfer_encoding,
- NULL, part_data);
- break;
+ if (hdr == NULL)
+ return;
+
+ parent_rfc822 = part->parent != NULL &&
+ (part->parent->flags & MESSAGE_PART_FLAG_MESSAGE_RFC822);
+ if (!parent_rfc822 && strncasecmp(hdr->name, "Content-", 8) != 0)
+ return;
+
+ if (part->context == NULL) {
+ /* initialize message part data */
+ part->context = part_data =
+ p_new(pool, struct message_part_body_data, 1);
+ part_data->pool = pool;
}
+ part_data = part->context;
+
+ t_push();
+
+ parse_content_header(part_data, hdr, pool);
if (parent_rfc822) {
/* message/rfc822, we need the envelope */
- imap_envelope_parse_header(pool, &part_data->envelope,
- name, name_len, value, value_len);
+ imap_envelope_parse_header(pool, &part_data->envelope, hdr);
}
t_pop();
}
@@ -249,7 +265,6 @@
(input->v_offset - start_offset));
message_parse_header(part, input, NULL, parse_header, pool);
-
if (part->children != NULL) {
part_parse_headers(part->children, input,
start_offset, pool);
Index: imap-envelope.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-imap/imap-envelope.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- imap-envelope.c 26 Mar 2003 15:40:16 -0000 1.24
+++ imap-envelope.c 26 Mar 2003 17:29:02 -0000 1.25
@@ -4,6 +4,7 @@
#include "istream.h"
#include "str.h"
#include "message-address.h"
+#include "message-parser.h"
#include "imap-parser.h"
#include "imap-envelope.h"
#include "imap-quote.h"
@@ -18,12 +19,80 @@
char *in_reply_to, *message_id;
};
+int imap_envelope_get_field(const char *name, enum imap_envelope_field *ret)
+{
+ *ret = (enum imap_envelope_field)-1;
+
+ switch (*name) {
+ case 'B':
+ case 'b':
+ if (strcasecmp(name, "Bcc") == 0)
+ *ret = IMAP_ENVELOPE_BCC;
+ break;
+ case 'C':
+ case 'c':
+ if (strcasecmp(name, "Cc") == 0)
+ *ret = IMAP_ENVELOPE_CC;
+ break;
+ case 'D':
+ case 'd':
+ if (strcasecmp(name, "Date") == 0)
+ *ret = IMAP_ENVELOPE_DATE;
+ break;
+ case 'F':
+ case 'f':
+ if (strcasecmp(name, "From") == 0)
+ *ret = IMAP_ENVELOPE_FROM;
+ break;
+ case 'I':
+ case 'i':
+ if (strcasecmp(name, "In-reply-to") == 0)
+ *ret = IMAP_ENVELOPE_IN_REPLY_TO;
+ break;
+ case 'M':
+ case 'm':
+ if (strcasecmp(name, "Message-id") == 0)
+ *ret = IMAP_ENVELOPE_MESSAGE_ID;
+ break;
+ case 'R':
+ case 'r':
+ if (strcasecmp(name, "Reply-to") == 0)
+ *ret = IMAP_ENVELOPE_REPLY_TO;
+ break;
+ case 'S':
+ case 's':
+ if (strcasecmp(name, "Subject") == 0)
+ *ret = IMAP_ENVELOPE_SUBJECT;
+ if (strcasecmp(name, "Sender") == 0)
+ *ret = IMAP_ENVELOPE_SENDER;
+ break;
+ case 'T':
+ case 't':
+ if (strcasecmp(name, "To") == 0)
+ *ret = IMAP_ENVELOPE_TO;
+ break;
+ }
+
+ return *ret != (enum imap_envelope_field)-1;
+}
+
void imap_envelope_parse_header(pool_t pool,
struct message_part_envelope_data **data,
- const unsigned char *name, size_t name_len,
- const unsigned char *value, size_t value_len)
+ struct message_header_line *hdr)
{
struct message_part_envelope_data *d;
+ enum imap_envelope_field field;
+ struct message_address **addr_p;
+ char **str_p;
+
+ if (hdr == NULL || !imap_envelope_get_field(hdr->name, &field))
+ return;
+
+ if (hdr->continues) {
+ /* wait for full value */
+ hdr->use_full_value = TRUE;
+ return;
+ }
if (*data == NULL) {
*data = p_new(pool, struct message_part_envelope_data, 1);
@@ -31,61 +100,50 @@
}
d = *data;
- t_push();
-
- switch (name_len) {
- case 2:
- if (memcasecmp(name, "To", 2) == 0 && d->to == NULL) {
- d->to = message_address_parse(pool, value,
- value_len, 0);
- } else if (memcasecmp(name, "Cc", 2) == 0 && d->cc == NULL) {
- d->cc = message_address_parse(pool, value,
- value_len, 0);
- }
+ addr_p = NULL; str_p = NULL;
+ switch (field) {
+ case IMAP_ENVELOPE_DATE:
+ str_p = &d->date;
break;
- case 3:
- if (memcasecmp(name, "Bcc", 3) == 0 && d->bcc == NULL) {
- d->bcc = message_address_parse(pool, value,
- value_len, 0);
- }
+ case IMAP_ENVELOPE_SUBJECT:
+ str_p = &d->subject;
break;
- case 4:
- if (memcasecmp(name, "From", 4) == 0 && d->from == NULL) {
- d->from = message_address_parse(pool, value,
- value_len, 0);
- } else if (memcasecmp(name, "Date", 4) == 0 && d->date == NULL)
- d->date = imap_quote(pool, value, value_len);
+ case IMAP_ENVELOPE_MESSAGE_ID:
+ str_p = &d->message_id;
break;
- case 6:
- if (memcasecmp(name, "Sender", 6) == 0 && d->sender == NULL) {
- d->sender = message_address_parse(pool, value,
- value_len, 0);
- }
+ case IMAP_ENVELOPE_IN_REPLY_TO:
+ str_p = &d->in_reply_to;
break;
- case 7:
- if (memcasecmp(name, "Subject", 7) == 0 && d->subject == NULL)
- d->subject = imap_quote(pool, value, value_len);
+
+ case IMAP_ENVELOPE_CC:
+ addr_p = &d->cc;
break;
- case 8:
- if (memcasecmp(name, "Reply-To", 8) == 0 &&
- d->reply_to == NULL) {
- d->reply_to = message_address_parse(pool, value,
- value_len, 0);
- }
+ case IMAP_ENVELOPE_BCC:
+ addr_p = &d->bcc;
break;
- case 10:
- if (memcasecmp(name, "Message-Id", 10) == 0 &&
- d->message_id == NULL)
- d->message_id = imap_quote(pool, value, value_len);
+ case IMAP_ENVELOPE_FROM:
+ addr_p = &d->from;
break;
- case 11:
- if (memcasecmp(name, "In-Reply-To", 11) == 0 &&
- d->in_reply_to == NULL)
- d->in_reply_to = imap_quote(pool, value, value_len);
+ case IMAP_ENVELOPE_SENDER:
+ addr_p = &d->sender;
+ break;
+ case IMAP_ENVELOPE_TO:
+ addr_p = &d->to;
+ break;
+ case IMAP_ENVELOPE_REPLY_TO:
+ addr_p = &d->reply_to;
+ break;
+ case IMAP_ENVELOPE_FIELDS:
break;
}
- t_pop();
+ if (addr_p != NULL) {
+ *addr_p = message_address_parse(pool, hdr->full_value,
+ hdr->full_value_len, 0);
+ }
+
+ if (str_p != NULL)
+ *str_p = imap_quote(pool, hdr->full_value, hdr->full_value_len);
}
static void imap_write_address(string_t *str, struct message_address *addr)
Index: imap-envelope.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-imap/imap-envelope.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- imap-envelope.h 26 Mar 2003 15:40:16 -0000 1.9
+++ imap-envelope.h 26 Mar 2003 17:29:02 -0000 1.10
@@ -1,6 +1,8 @@
#ifndef __IMAP_ENVELOPE_H
#define __IMAP_ENVELOPE_H
+struct message_header_line;
+
enum imap_envelope_field {
/* NOTE: in the same order as listed in ENVELOPE */
IMAP_ENVELOPE_DATE = 0,
@@ -24,11 +26,12 @@
struct message_part_envelope_data;
+int imap_envelope_get_field(const char *name, enum imap_envelope_field *ret);
+
/* Update envelope data based from given header field */
void imap_envelope_parse_header(pool_t pool,
struct message_part_envelope_data **data,
- const unsigned char *name, size_t name_len,
- const unsigned char *value, size_t value_len);
+ struct message_header_line *hdr);
/* Write envelope to given string */
void imap_envelope_write_part_data(struct message_part_envelope_data *data,
Index: imap-quote.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-imap/imap-quote.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- imap-quote.c 26 Mar 2003 15:40:16 -0000 1.10
+++ imap-quote.c 26 Mar 2003 17:29:02 -0000 1.11
@@ -53,11 +53,18 @@
char *imap_quote(pool_t pool, const unsigned char *value, size_t value_len)
{
string_t *str;
+ char *ret;
+
+ i_assert(pool != data_stack_pool);
if (value == NULL)
return "NIL";
+ t_push();
str = t_str_new(value_len + MAX_INT_STRLEN + 5);
imap_quote_append(str, value, value_len);
- return p_strndup(pool, str_data(str), str_len(str));
+ ret = p_strndup(pool, str_data(str), str_len(str));
+ t_pop();
+
+ return ret;
}
More information about the dovecot-cvs
mailing list