[dovecot-cvs] dovecot/src/lib-mail message-parser.c,1.41,1.42
message-parser.h,1.19,1.20 message-send.c,1.17,1.18
message-send.h,1.10,1.11 message-size.c,1.12,1.13
message-size.h,1.10,1.11
cras at procontrol.fi
cras at procontrol.fi
Wed Jun 4 19:58:01 EEST 2003
Update of /home/cvs/dovecot/src/lib-mail
In directory danu:/tmp/cvs-serv27024/lib-mail
Modified Files:
message-parser.c message-parser.h message-send.c
message-send.h message-size.c message-size.h
Log Message:
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
instead.
Index: message-parser.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-mail/message-parser.c,v
retrieving revision 1.41
retrieving revision 1.42
diff -u -d -r1.41 -r1.42
--- message-parser.c 4 Jun 2003 14:47:22 -0000 1.41
+++ message-parser.c 4 Jun 2003 15:57:58 -0000 1.42
@@ -38,6 +38,8 @@
string_t *name;
buffer_t *value_buf;
size_t skip;
+
+ int has_nuls;
};
static struct message_part *
@@ -46,12 +48,12 @@
static struct message_part *
message_parse_body(struct istream *input, struct message_boundary *boundaries,
- struct message_size *body_size);
+ struct message_size *body_size, int *has_nuls);
static struct message_part *
message_skip_boundary(struct istream *input,
struct message_boundary *boundaries,
- struct message_size *boundary_size);
+ struct message_size *boundary_size, int *has_nuls);
static void message_size_add_part(struct message_size *dest,
struct message_part *part)
@@ -138,6 +140,7 @@
{
struct message_part *parent_part, *next_part, *part;
struct message_boundary *b;
+ int has_nuls;
/* multipart message. add new boundary */
b = t_new(struct message_boundary, 1);
@@ -155,7 +158,9 @@
/* skip the data before the first boundary */
parent_part = parser_ctx->part;
next_part = message_skip_boundary(input, parser_ctx->boundaries,
- &parent_part->body_size);
+ &parent_part->body_size, &has_nuls);
+ if (has_nuls)
+ parent_part->flags |= MESSAGE_PART_FLAG_HAS_NULS;
/* now, parse the parts */
while (next_part == parent_part) {
@@ -165,6 +170,11 @@
parser_ctx->part = part;
next_part = message_parse_part(input, parser_ctx);
+ if ((part->flags & MESSAGE_PART_FLAG_HAS_NULS) != 0) {
+ /* it also belongs to parent */
+ parent_part->flags |= MESSAGE_PART_FLAG_HAS_NULS;
+ }
+
/* update our size */
message_size_add_part(&parent_part->body_size, part);
@@ -173,7 +183,10 @@
/* skip the boundary */
next_part = message_skip_boundary(input, parser_ctx->boundaries,
- &parent_part->body_size);
+ &parent_part->body_size,
+ &has_nuls);
+ if (has_nuls)
+ parent_part->flags |= MESSAGE_PART_FLAG_HAS_NULS;
}
/* remove boundary */
@@ -192,6 +205,7 @@
struct message_header_line *hdr;
struct message_part *next_part, *part;
uoff_t hdr_size;
+ int has_nuls;
hdr_ctx = message_parse_header_init(input,
&parser_ctx->part->header_size);
@@ -219,6 +233,8 @@
parser_ctx->callback(parser_ctx->part, NULL,
parser_ctx->context);
}
+ if (hdr_ctx->has_nuls)
+ parser_ctx->part->flags |= MESSAGE_PART_FLAG_HAS_NULS;
message_parse_header_deinit(hdr_ctx);
i_assert((parser_ctx->part->flags & MUTEX_FLAGS) != MUTEX_FLAGS);
@@ -263,23 +279,35 @@
/* normal message, read until the next boundary */
part = parser_ctx->part;
next_part = message_parse_body(input, parser_ctx->boundaries,
- &part->body_size);
+ &part->body_size, &has_nuls);
+ if (has_nuls)
+ part->flags |= MESSAGE_PART_FLAG_HAS_NULS;
+ }
+
+ if ((part->flags & MESSAGE_PART_FLAG_HAS_NULS) != 0 &&
+ part->parent != NULL) {
+ /* it also belongs to parent */
+ part->parent->flags |= MESSAGE_PART_FLAG_HAS_NULS;
}
return next_part;
}
static void message_skip_line(struct istream *input,
- struct message_size *msg_size, int skip_lf)
+ struct message_size *msg_size, int skip_lf,
+ int *has_nuls)
{
const unsigned char *msg;
size_t i, size, startpos;
startpos = 0;
+ *has_nuls = FALSE;
while (i_stream_read_data(input, &msg, &size, startpos) > 0) {
for (i = startpos; i < size; i++) {
- if (msg[i] == '\n') {
+ if (msg[i] == '\0')
+ *has_nuls = TRUE;
+ else if (msg[i] == '\n') {
if (!skip_lf) {
if (i > 0 && msg[i-1] == '\r')
i--;
@@ -336,7 +364,8 @@
static struct message_boundary *
message_find_boundary(struct istream *input,
struct message_boundary *boundaries,
- struct message_size *msg_size, int skip_over)
+ struct message_size *msg_size, int skip_over,
+ int *has_nuls)
{
struct message_boundary *boundary;
const unsigned char *msg;
@@ -344,11 +373,15 @@
boundary = NULL;
missing_cr_count = startpos = line_start = 0;
+ *has_nuls = FALSE;
while (i_stream_read_data(input, &msg, &size, startpos) > 0) {
for (i = startpos; i < size; i++) {
- if (msg[i] != '\n')
+ if (msg[i] != '\n') {
+ if (msg[i] == '\0')
+ *has_nuls = TRUE;
continue;
+ }
if (line_start != (size_t)-1 &&
i >= line_start+2 && msg[line_start] == '-' &&
@@ -447,20 +480,22 @@
static struct message_part *
message_parse_body(struct istream *input, struct message_boundary *boundaries,
- struct message_size *msg_size)
+ struct message_size *msg_size, int *has_nuls)
{
struct message_boundary *boundary;
struct message_size body_size;
if (boundaries == NULL) {
- message_get_body_size(input, &body_size, (uoff_t)-1, NULL);
+ message_get_body_size(input, &body_size,
+ (uoff_t)-1, NULL, has_nuls);
message_size_add(msg_size, &body_size);
- return NULL;
+ boundary = NULL;
} else {
boundary = message_find_boundary(input, boundaries,
- msg_size, FALSE);
- return boundary == NULL ? NULL : boundary->part;
+ msg_size, FALSE, has_nuls);
}
+
+ return boundary == NULL ? NULL : boundary->part;
}
/* skip data until next boundary is found. if it's end boundary,
@@ -468,7 +503,7 @@
static struct message_part *
message_skip_boundary(struct istream *input,
struct message_boundary *boundaries,
- struct message_size *boundary_size)
+ struct message_size *boundary_size, int *has_nuls)
{
struct message_boundary *boundary;
const unsigned char *msg;
@@ -476,7 +511,7 @@
int end_boundary;
boundary = message_find_boundary(input, boundaries,
- boundary_size, TRUE);
+ boundary_size, TRUE, has_nuls);
if (boundary == NULL)
return NULL;
@@ -486,11 +521,12 @@
end_boundary = msg[0] == '-' && msg[1] == '-';
/* skip the rest of the line */
- message_skip_line(input, boundary_size, !end_boundary);
+ message_skip_line(input, boundary_size, !end_boundary, has_nuls);
if (end_boundary) {
/* skip the footer */
- return message_parse_body(input, boundary->next, boundary_size);
+ return message_parse_body(input, boundary->next,
+ boundary_size, has_nuls);
}
return boundary == NULL ? NULL : boundary->part;
@@ -615,7 +651,7 @@
if (colon_pos == UINT_MAX) {
/* header name is huge. just skip it. */
message_skip_line(ctx->input, ctx->hdr_size,
- TRUE);
+ TRUE, &ctx->has_nuls);
continue;
}
@@ -645,14 +681,21 @@
/* end of headers, or error */
break;
}
+
+ if (msg[i] == '\0')
+ ctx->has_nuls = TRUE;
}
}
}
/* find '\n' */
for (i = startpos; i < parse_size; i++) {
- if (msg[i] == '\n')
- break;
+ if (msg[i] <= '\n') {
+ if (msg[i] == '\n')
+ break;
+ if (msg[i] == '\0')
+ ctx->has_nuls = TRUE;
+ }
}
if (i < parse_size) {
Index: message-parser.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-mail/message-parser.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- message-parser.h 26 Mar 2003 17:29:02 -0000 1.19
+++ message-parser.h 4 Jun 2003 15:57:58 -0000 1.20
@@ -15,7 +15,10 @@
MESSAGE_PART_FLAG_TEXT = 0x08,
/* content-transfer-encoding: binary */
- MESSAGE_PART_FLAG_BINARY = 0x10
+ MESSAGE_PART_FLAG_BINARY = 0x10,
+
+ /* message part header or body contains NULs */
+ MESSAGE_PART_FLAG_HAS_NULS = 0x20
};
struct message_part {
Index: message-send.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-mail/message-send.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- message-send.c 26 Apr 2003 21:52:38 -0000 1.17
+++ message-send.c 4 Jun 2003 15:57:58 -0000 1.18
@@ -9,13 +9,14 @@
off_t message_send(struct ostream *output, struct istream *input,
const struct message_size *msg_size,
- uoff_t virtual_skip, uoff_t max_virtual_size, int *last_cr)
+ uoff_t virtual_skip, uoff_t max_virtual_size, int *last_cr,
+ int fix_nuls)
{
const unsigned char *msg;
uoff_t old_limit, limit;
size_t i, size;
off_t ret;
- int cr_skipped, add_cr;
+ int cr_skipped, add;
if (last_cr != NULL)
*last_cr = -1;
@@ -27,7 +28,7 @@
if (max_virtual_size > msg_size->virtual_size - virtual_skip)
max_virtual_size = msg_size->virtual_size - virtual_skip;
- if (msg_size->physical_size == msg_size->virtual_size) {
+ if (msg_size->physical_size == msg_size->virtual_size && !fix_nuls) {
/* no need to kludge with CRs, we can use sendfile() */
i_stream_skip(input, virtual_skip);
@@ -46,7 +47,7 @@
ret = 0;
while (max_virtual_size > 0 &&
i_stream_read_data(input, &msg, &size, 0) > 0) {
- add_cr = FALSE;
+ add = '\0';
for (i = 0; i < size && max_virtual_size > 0; i++) {
max_virtual_size--;
@@ -54,9 +55,12 @@
if ((i == 0 && !cr_skipped) ||
(i > 0 && msg[i-1] != '\r')) {
/* missing CR */
- add_cr = TRUE;
+ add = '\r';
break;
}
+ } else if (msg[i] == '\0') {
+ add = 128;
+ break;
}
}
@@ -64,11 +68,12 @@
if (o_stream_send(output, msg, i) < 0)
return -1;
- if (add_cr) {
+ if (add != '\0') {
ret++;
- if (o_stream_send(output, "\r", 1) < 0)
+ if (o_stream_send(output, &add, 1) < 0)
return -1;
- cr_skipped = TRUE;
+ cr_skipped = add == '\r';
+ if (add == 128) i++;
} else {
cr_skipped = i > 0 && msg[i-1] == '\r';
}
Index: message-send.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-mail/message-send.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- message-send.h 26 Apr 2003 21:52:38 -0000 1.10
+++ message-send.h 4 Jun 2003 15:57:58 -0000 1.11
@@ -10,7 +10,8 @@
known. Returns number of bytes sent, or -1 if error. */
off_t message_send(struct ostream *output, struct istream *input,
const struct message_size *msg_size,
- uoff_t virtual_skip, uoff_t max_virtual_size, int *last_cr);
+ uoff_t virtual_skip, uoff_t max_virtual_size, int *last_cr,
+ int fix_nuls);
/* Skip number of virtual bytes from putfer. msg_size is updated if it's not
NULL. If cr_skipped is TRUE and first character is \n, it's not treated as
Index: message-size.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-mail/message-size.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- message-size.c 26 Apr 2003 21:52:38 -0000 1.12
+++ message-size.c 4 Jun 2003 15:57:58 -0000 1.13
@@ -5,18 +5,24 @@
#include "message-parser.h"
#include "message-size.h"
-void message_get_header_size(struct istream *input, struct message_size *hdr)
+void message_get_header_size(struct istream *input, struct message_size *hdr,
+ int *has_nuls)
{
const unsigned char *msg;
size_t i, size, startpos, missing_cr_count;
memset(hdr, 0, sizeof(struct message_size));
+ if (has_nuls != NULL)
+ *has_nuls = FALSE;
missing_cr_count = 0; startpos = 0;
while (i_stream_read_data(input, &msg, &size, startpos) > 0) {
for (i = startpos; i < size; i++) {
- if (msg[i] != '\n')
+ if (msg[i] != '\n') {
+ if (msg[i] == '\0' && has_nuls != NULL)
+ *has_nuls = TRUE;
continue;
+ }
hdr->lines++;
if (i == 0 || msg[i-1] != '\r') {
@@ -56,13 +62,15 @@
}
void message_get_body_size(struct istream *input, struct message_size *body,
- uoff_t max_virtual_size, int *last_cr)
+ uoff_t max_virtual_size, int *last_cr, int *has_nuls)
{
const unsigned char *msg;
size_t i, size, startpos, missing_cr_count;
int cr;
memset(body, 0, sizeof(struct message_size));
+ if (has_nuls != NULL)
+ *has_nuls = FALSE;
cr = 0;
missing_cr_count = 0; startpos = 0;
@@ -72,7 +80,10 @@
for (i = startpos; i < size && max_virtual_size > 0; i++) {
max_virtual_size--;
- if (msg[i] == '\n') {
+ if (msg[i] == '\0') {
+ if (has_nuls != NULL)
+ *has_nuls = TRUE;
+ } else if (msg[i] == '\n') {
if (i == 0 || msg[i-1] != '\r') {
/* missing CR */
missing_cr_count++;
Index: message-size.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-mail/message-size.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- message-size.h 26 Apr 2003 21:52:38 -0000 1.10
+++ message-size.h 4 Jun 2003 15:57:58 -0000 1.11
@@ -9,12 +9,14 @@
/* Calculate size of message header. Leave the input point to first
character in body. */
-void message_get_header_size(struct istream *input, struct message_size *hdr);
+void message_get_header_size(struct istream *input, struct message_size *hdr,
+ int *has_nuls);
/* Calculate size of message body. Read only max_virtual_size virtual bytes,
if you want it unlimited, use (uoff_t)-1. If last_cr is not NULL, it's set
to 1 if last character is CR, 2 if it's virtual CR. */
void message_get_body_size(struct istream *input, struct message_size *body,
- uoff_t max_virtual_size, int *last_cr);
+ uoff_t max_virtual_size, int *last_cr,
+ int *has_nuls);
/* Sum contents of src into dest. */
void message_size_add(struct message_size *dest,
More information about the dovecot-cvs
mailing list