changeset 339:6f4eeb6a0a0d HEAD

Several fields in BODY were unquoted.
author Timo Sirainen <tss@iki.fi>
date Tue, 01 Oct 2002 00:18:12 +0300
parents 36ab6a6c8bdf
children 37d52d6a3e7a
files src/lib-imap/Makefile.am src/lib-imap/imap-bodystructure.c src/lib-imap/imap-envelope.c src/lib-imap/imap-quote.c src/lib-imap/imap-quote.h
diffstat 5 files changed, 203 insertions(+), 183 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-imap/Makefile.am	Mon Sep 30 23:36:29 2002 +0300
+++ b/src/lib-imap/Makefile.am	Tue Oct 01 00:18:12 2002 +0300
@@ -10,6 +10,7 @@
 	imap-envelope.c \
 	imap-match.c \
 	imap-message-cache.c \
+	imap-quote.c \
 	imap-parser.c \
 	imap-util.c
 
@@ -19,5 +20,6 @@
 	imap-envelope.h \
 	imap-match.h \
 	imap-message-cache.h \
+	imap-quote.h \
 	imap-parser.h \
 	imap-util.h
--- a/src/lib-imap/imap-bodystructure.c	Mon Sep 30 23:36:29 2002 +0300
+++ b/src/lib-imap/imap-bodystructure.c	Tue Oct 01 00:18:12 2002 +0300
@@ -8,6 +8,7 @@
 #include "message-content-parser.h"
 #include "imap-envelope.h"
 #include "imap-bodystructure.h"
+#include "imap-quote.h"
 
 #define EMPTY_BODYSTRUCTURE \
         "(\"text\" \"plain\" (\"charset\" \"us-ascii\") NIL NIL \"7bit\" 0 0)"
@@ -145,10 +146,11 @@
 						parse_content_transfer_encoding,
 						NULL, part_data);
 	} else if (strcasecmp(name, "Content-ID") == 0) {
-		part_data->content_id = p_strndup(pool, value, value_len);
+		part_data->content_id =
+			imap_quote_value(pool, value, value_len);
 	} else if (strcasecmp(name, "Content-Description") == 0) {
 		part_data->content_description =
-			p_strndup(pool, value, value_len);
+			imap_quote_value(pool, value, value_len);
 	} else if (strcasecmp(name, "Content-Disposition") == 0) {
 		part_data->str = t_string_new(256);
 		(void)message_content_parse_header(t_strndup(value, value_len),
@@ -162,7 +164,8 @@
 						   parse_content_language, NULL,
 						   part_data);
 	} else if (strcasecmp(name, "Content-MD5") == 0) {
-		part_data->content_md5 = p_strndup(pool, value, value_len);
+		part_data->content_md5 =
+			imap_quote_value(pool, value, value_len);
 	} else if (parent_rfc822) {
 		/* message/rfc822, we need the envelope */
 		imap_envelope_parse_header(pool, &part_data->envelope,
--- a/src/lib-imap/imap-envelope.c	Mon Sep 30 23:36:29 2002 +0300
+++ b/src/lib-imap/imap-envelope.c	Tue Oct 01 00:18:12 2002 +0300
@@ -4,6 +4,7 @@
 #include "temp-string.h"
 #include "rfc822-address.h"
 #include "imap-envelope.h"
+#include "imap-quote.h"
 
 struct _MessagePartEnvelopeData {
 	Pool pool;
@@ -15,178 +16,6 @@
 	char *in_reply_to, *message_id;
 };
 
-#define IS_BREAK_CHAR(c) \
-	((c) == ' ' || (c) == '\t' || \
-	 (c) == ',' || (c) == ':' || (c) == ';' || (c) == '@' || \
-	 (c) == '<' || (c) == '>' || (c) == '(' || (c) == ')' || \
-	 (c) == '[' || (c) == ']' || (c) == '=')
-
-#define IS_BREAK_OR_CRLF_CHAR(c) \
-	(IS_BREAK_CHAR(c) || (c) == '\r' || (c) == '\n')
-
-static size_t next_token_quoted(const char *value, size_t len,
-				int *need_qp, int *quoted)
-{
-	size_t i;
-
-	*need_qp = FALSE;
-	*quoted = TRUE;
-
-	for (i = *quoted ? 0 : 1; i < len; i++) {
-		if ((unsigned char)value[i] & 0x80)
-			*need_qp = TRUE;
-
-		if (value[i] == '"' || value[i] == '\r' || value[i] == '\n') {
-			i++;
-			*quoted = value[i] == '"';
-			break;
-		}
-	}
-
-	return i;
-}
-
-static size_t next_token(const char *value, size_t len,
-			 int *need_qp, int *quoted, int qp_on)
-{
-	size_t i = 0;
-
-	if (value[0] == '"' || *quoted)
-		return next_token_quoted(value, len, need_qp, quoted);
-
-	*need_qp = FALSE;
-
-	if (qp_on) {
-		/* skip spaces, so we don't end up QP'ing word at a time */
-		for (i = 0; i < len; i++) {
-			if (value[i] != ' ')
-				break;
-		}
-
-		if (i == len)
-			return i;
-	}
-
-	if (IS_BREAK_OR_CRLF_CHAR(value[i])) {
-		/* return all break-chars in one token */
-		for (i++; i < len; i++) {
-			if (!IS_BREAK_CHAR(value[i]))
-				break;
-		}
-
-		return i;
-	}
-
-	/* then stop at break-char */
-	for (; i < len; i++) {
-		if ((unsigned char)value[i] & 0x80)
-			*need_qp = TRUE;
-
-		if (IS_BREAK_OR_CRLF_CHAR(value[i]))
-			break;
-	}
-
-	return i;
-}
-
-static void append_quoted_qp(TempString *str, const char *value, size_t len)
-{
-	size_t i;
-	unsigned char c;
-
-	/* do this the easy way, it's already broken behaviour to leave the
-	   8bit text in mailbox, so we shouldn't need to try too hard to make
-	   it readable. Keep 'A'..'Z', 'a'..'z' and '0'..'9', QP rest */
-
-	for (i = 0; i < len; i++) {
-		if (value[i] == ' ')
-			t_string_append_c(str, '_');
-		else if ((value[i] >= 'A' && value[i] <= 'Z') ||
-			 (value[i] >= 'a' && value[i] <= 'z') ||
-			 (value[i] >= '0' && value[i] <= '9')) {
-			t_string_append_c(str, value[i]);
-		} else {
-			t_string_append_c(str, '=');
-			c = (unsigned char)value[i] >> 4;
-			t_string_append_c(str, c < 10 ? (c+'0') : (c-10+'A'));
-			c = (unsigned char)value[i] & 0x0f;
-			t_string_append_c(str, c < 10 ? (c+'0') : (c-10+'A'));
-		}
-	}
-}
-
-static void append_quoted(TempString *str, const char *value, size_t len)
-{
-	size_t i;
-
-	for (i = 0; i < len; i++) {
-		if (value[i] == '\\' || value[i] == '"')
-			t_string_append_c(str, '\\');
-		t_string_append_c(str, value[i]);
-	}
-}
-
-/* does two things: 1) escape '\' and '"' characters, 2) 8bit text -> QP */
-static TempString *get_quoted_str(const char *value, size_t value_len)
-{
-	TempString *str;
-	size_t token_len;
-	int qp, need_qp, quoted;
-
-	str = t_string_new(value_len * 2);
-	qp = FALSE;
-	quoted = FALSE;
-
-	t_string_append_c(str, '"');
-	while (value_len > 0) {
-		token_len = next_token(value, value_len, &need_qp, &quoted, qp);
-		i_assert(token_len > 0 && token_len <= value_len);
-
-		/* header may be split to multiple lines, we don't want them */
-		while (token_len > 0 && (value[0] == '\r' ||
-					 value[0] == '\n')) {
-			value++;
-			token_len--;
-			value_len--;
-		}
-
-		if (need_qp && !qp) {
-			t_string_append(str, "=?x-unknown?Q?");
-			qp = TRUE;
-		} else if (!need_qp && qp) {
-			t_string_append(str, "?=");
-			qp = FALSE;
-		}
-
-		if (need_qp)
-			append_quoted_qp(str, value, token_len);
-		else
-			append_quoted(str, value, token_len);
-
-		value += token_len;
-		value_len -= token_len;
-	}
-
-	if (qp) t_string_append(str, "?=");
-	t_string_append_c(str, '"');
-
-	return str;
-}
-
-static const char *quote_str_nil(const char *value)
-{
-	return value == NULL ? "NIL" :
-		get_quoted_str(value, strlen(value))->str;
-}
-
-static char *quote_value(Pool pool, const char *value, size_t value_len)
-{
-	TempString *str;
-
-	str = get_quoted_str(value, value_len);
-	return p_strndup(pool, str->str, str->len);
-}
-
 static Rfc822Address *parse_address(Pool pool, const char *value,
 				    size_t value_len)
 {
@@ -208,9 +37,9 @@
 	}
 
 	if (strcasecmp(name, "Date") == 0)
-		(*data)->date = quote_value(pool, value, value_len);
+		(*data)->date = imap_quote_value(pool, value, value_len);
 	else if (strcasecmp(name, "Subject") == 0)
-		(*data)->subject = quote_value(pool, value, value_len);
+		(*data)->subject = imap_quote_value(pool, value, value_len);
 	else if (strcasecmp(name, "From") == 0)
 		(*data)->from = parse_address(pool, value, value_len);
 	else if (strcasecmp(name, "Sender") == 0)
@@ -224,9 +53,9 @@
 	else if (strcasecmp(name, "Bcc") == 0)
 		(*data)->bcc = parse_address(pool, value, value_len);
 	else if (strcasecmp(name, "In-Reply-To") == 0)
-		(*data)->in_reply_to = quote_value(pool, value, value_len);
+		(*data)->in_reply_to = imap_quote_value(pool, value, value_len);
 	else if (strcasecmp(name, "Message-Id") == 0)
-		(*data)->message_id = quote_value(pool, value, value_len);
+		(*data)->message_id = imap_quote_value(pool, value, value_len);
 }
 
 static void imap_write_address(TempString *str, Rfc822Address *addr)
@@ -239,13 +68,13 @@
 	t_string_append_c(str, '(');
 	while (addr != NULL) {
 		t_string_append_c(str, '(');
-		t_string_append(str, quote_str_nil(addr->name));
+		t_string_append(str, imap_quote_str_nil(addr->name));
 		t_string_append_c(str, ' ');
-		t_string_append(str, quote_str_nil(addr->route));
+		t_string_append(str, imap_quote_str_nil(addr->route));
 		t_string_append_c(str, ' ');
-		t_string_append(str, quote_str_nil(addr->mailbox));
+		t_string_append(str, imap_quote_str_nil(addr->mailbox));
 		t_string_append_c(str, ' ');
-		t_string_append(str, quote_str_nil(addr->domain));
+		t_string_append(str, imap_quote_str_nil(addr->domain));
 		t_string_append_c(str, ')');
 
 		addr = addr->next;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-imap/imap-quote.c	Tue Oct 01 00:18:12 2002 +0300
@@ -0,0 +1,176 @@
+/* Copyright (C) 2002 Timo Sirainen */
+
+#include "lib.h"
+#include "temp-string.h"
+
+#define IS_BREAK_CHAR(c) \
+	((c) == ' ' || (c) == '\t' || \
+	 (c) == ',' || (c) == ':' || (c) == ';' || (c) == '@' || \
+	 (c) == '<' || (c) == '>' || (c) == '(' || (c) == ')' || \
+	 (c) == '[' || (c) == ']' || (c) == '=')
+
+#define IS_BREAK_OR_CRLF_CHAR(c) \
+	(IS_BREAK_CHAR(c) || (c) == '\r' || (c) == '\n')
+
+static size_t next_token_quoted(const char *value, size_t len,
+				int *need_qp, int *quoted)
+{
+	size_t i;
+
+	*need_qp = FALSE;
+	*quoted = TRUE;
+
+	for (i = *quoted ? 0 : 1; i < len; i++) {
+		if ((unsigned char)value[i] & 0x80)
+			*need_qp = TRUE;
+
+		if (value[i] == '"' || value[i] == '\r' || value[i] == '\n') {
+			i++;
+			*quoted = value[i] == '"';
+			break;
+		}
+	}
+
+	return i;
+}
+
+static size_t next_token(const char *value, size_t len,
+			 int *need_qp, int *quoted, int qp_on)
+{
+	size_t i = 0;
+
+	if (value[0] == '"' || *quoted)
+		return next_token_quoted(value, len, need_qp, quoted);
+
+	*need_qp = FALSE;
+
+	if (qp_on) {
+		/* skip spaces, so we don't end up QP'ing word at a time */
+		for (i = 0; i < len; i++) {
+			if (value[i] != ' ')
+				break;
+		}
+
+		if (i == len)
+			return i;
+	}
+
+	if (IS_BREAK_OR_CRLF_CHAR(value[i])) {
+		/* return all break-chars in one token */
+		for (i++; i < len; i++) {
+			if (!IS_BREAK_CHAR(value[i]))
+				break;
+		}
+
+		return i;
+	}
+
+	/* then stop at break-char */
+	for (; i < len; i++) {
+		if ((unsigned char)value[i] & 0x80)
+			*need_qp = TRUE;
+
+		if (IS_BREAK_OR_CRLF_CHAR(value[i]))
+			break;
+	}
+
+	return i;
+}
+
+static void append_quoted_qp(TempString *str, const char *value, size_t len)
+{
+	size_t i;
+	unsigned char c;
+
+	/* do this the easy way, it's already broken behaviour to leave the
+	   8bit text in mailbox, so we shouldn't need to try too hard to make
+	   it readable. Keep 'A'..'Z', 'a'..'z' and '0'..'9', QP rest */
+
+	for (i = 0; i < len; i++) {
+		if (value[i] == ' ')
+			t_string_append_c(str, '_');
+		else if ((value[i] >= 'A' && value[i] <= 'Z') ||
+			 (value[i] >= 'a' && value[i] <= 'z') ||
+			 (value[i] >= '0' && value[i] <= '9')) {
+			t_string_append_c(str, value[i]);
+		} else {
+			t_string_append_c(str, '=');
+			c = (unsigned char)value[i] >> 4;
+			t_string_append_c(str, c < 10 ? (c+'0') : (c-10+'A'));
+			c = (unsigned char)value[i] & 0x0f;
+			t_string_append_c(str, c < 10 ? (c+'0') : (c-10+'A'));
+		}
+	}
+}
+
+static void append_quoted(TempString *str, const char *value, size_t len)
+{
+	size_t i;
+
+	for (i = 0; i < len; i++) {
+		if (value[i] == '\\' || value[i] == '"')
+			t_string_append_c(str, '\\');
+		t_string_append_c(str, value[i]);
+	}
+}
+
+/* does two things: 1) escape '\' and '"' characters, 2) 8bit text -> QP */
+static TempString *get_quoted_str(const char *value, size_t value_len)
+{
+	TempString *str;
+	size_t token_len;
+	int qp, need_qp, quoted;
+
+	str = t_string_new(value_len * 2);
+	qp = FALSE;
+	quoted = FALSE;
+
+	t_string_append_c(str, '"');
+	while (value_len > 0) {
+		token_len = next_token(value, value_len, &need_qp, &quoted, qp);
+		i_assert(token_len > 0 && token_len <= value_len);
+
+		/* header may be split to multiple lines, we don't want them */
+		while (token_len > 0 && (value[0] == '\r' ||
+					 value[0] == '\n')) {
+			value++;
+			token_len--;
+			value_len--;
+		}
+
+		if (need_qp && !qp) {
+			t_string_append(str, "=?x-unknown?Q?");
+			qp = TRUE;
+		} else if (!need_qp && qp) {
+			t_string_append(str, "?=");
+			qp = FALSE;
+		}
+
+		if (need_qp)
+			append_quoted_qp(str, value, token_len);
+		else
+			append_quoted(str, value, token_len);
+
+		value += token_len;
+		value_len -= token_len;
+	}
+
+	if (qp) t_string_append(str, "?=");
+	t_string_append_c(str, '"');
+
+	return str;
+}
+
+const char *imap_quote_str_nil(const char *value)
+{
+	return value == NULL ? "NIL" :
+		get_quoted_str(value, strlen(value))->str;
+}
+
+char *imap_quote_value(Pool pool, const char *value, size_t value_len)
+{
+	TempString *str;
+
+	str = get_quoted_str(value, value_len);
+	return p_strndup(pool, str->str, str->len);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-imap/imap-quote.h	Tue Oct 01 00:18:12 2002 +0300
@@ -0,0 +1,10 @@
+#ifndef __IMAP_QUOTE_H
+#define __IMAP_QUOTE_H
+
+/* If value is non-NULL, return it "quoted", otherwise return NIL unquoted. */
+const char *imap_quote_str_nil(const char *value);
+
+/* Return value quoted and allocated from specified pool. */
+char *imap_quote_value(Pool pool, const char *value, size_t value_len);
+
+#endif