[dovecot-cvs] dovecot/src/lib-imap imap-bodystructure.c,1.23,1.24 imap-envelope.c,1.17,1.18 imap-parser.c,1.27,1.28 imap-parser.h,1.6,1.7

cras at procontrol.fi cras at procontrol.fi
Thu Jan 2 10:09:29 EET 2003


Update of /home/cvs/dovecot/src/lib-imap
In directory danu:/tmp/cvs-serv14058/lib-imap

Modified Files:
	imap-bodystructure.c imap-envelope.c imap-parser.c 
	imap-parser.h 
Log Message:
Don't access ImapArg's union members directly - too easy to mess up. Fixes a
crash with feeding non-string parameters to SEARCH/SORT commands.



Index: imap-bodystructure.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-imap/imap-bodystructure.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- imap-bodystructure.c	27 Dec 2002 20:57:11 -0000	1.23
+++ imap-bodystructure.c	2 Jan 2003 08:09:27 -0000	1.24
@@ -456,15 +456,15 @@
 			str_append(str, "NIL");
 			break;
 		case IMAP_ARG_ATOM:
-			str_append(str, args->data.str);
+			str_append(str, IMAP_ARG_STR(args));
 			break;
 		case IMAP_ARG_STRING:
 			str_append_c(str, '"');
-			str_append(str, args->data.str);
+			str_append(str, IMAP_ARG_STR(args));
 			str_append_c(str, '"');
 			break;
 		case IMAP_ARG_LIST:
-			if (!imap_write_list(args->data.list->args, str))
+			if (!imap_write_list(IMAP_ARG_LIST(args)->args, str))
 				return FALSE;
 			break;
 		default:
@@ -482,12 +482,14 @@
 static int imap_parse_bodystructure_args(const ImapArg *args, String *str)
 {
 	ImapArg *subargs;
+	ImapArgList *list;
 	int i, multipart, text, message_rfc822;
 
 	multipart = FALSE;
 	while (args->type == IMAP_ARG_LIST) {
 		str_append_c(str, '(');
-		if (!imap_parse_bodystructure_args(args->data.list->args, str))
+		list = IMAP_ARG_LIST(args);
+		if (!imap_parse_bodystructure_args(list->args, str))
 			return FALSE;
 		str_append_c(str, ')');
 
@@ -500,7 +502,7 @@
 		if (args->type != IMAP_ARG_STRING)
 			return FALSE;
 
-		str_printfa(str, " \"%s\"", args->data.str);
+		str_printfa(str, " \"%s\"", IMAP_ARG_STR(args));
 		return TRUE;
 	}
 
@@ -508,24 +510,26 @@
 	if (args[0].type != IMAP_ARG_STRING || args[1].type != IMAP_ARG_STRING)
 		return FALSE;
 
-	text = strcasecmp(args[0].data.str, "text") == 0;
-	message_rfc822 = strcasecmp(args[0].data.str, "message") == 0 &&
-		strcasecmp(args[1].data.str, "rfc822") == 0;
+	text = strcasecmp(IMAP_ARG_STR(&args[0]), "text") == 0;
+	message_rfc822 = strcasecmp(IMAP_ARG_STR(&args[0]), "message") == 0 &&
+		strcasecmp(IMAP_ARG_STR(&args[1]), "rfc822") == 0;
 
-	str_printfa(str, "\"%s\" \"%s\"", args[0].data.str, args[1].data.str);
+	str_printfa(str, "\"%s\" \"%s\"", IMAP_ARG_STR(&args[0]),
+		    IMAP_ARG_STR(&args[1]));
 	args += 2;
 
 	/* ("content type param key" "value" ...) | NIL */
 	if (args->type == IMAP_ARG_LIST) {
 		str_append(str, " (");
-                subargs = args->data.list->args;
+                subargs = IMAP_ARG_LIST(args)->args;
 		for (; subargs->type != IMAP_ARG_EOL; ) {
 			if (subargs[0].type != IMAP_ARG_STRING ||
 			    subargs[1].type != IMAP_ARG_STRING)
 				return FALSE;
 
 			str_printfa(str, "\"%s\" \"%s\"",
-				    subargs[0].data.str, subargs[1].data.str);
+				    IMAP_ARG_STR(&subargs[0]),
+				    IMAP_ARG_STR(&subargs[1]));
 
 			subargs += 2;
 			if (subargs->type == IMAP_ARG_EOL)
@@ -546,9 +550,9 @@
 			str_append(str, " NIL");
 		} else if (args->type == IMAP_ARG_ATOM) {
 			str_append_c(str, ' ');
-			str_append(str, args->data.str);
+			str_append(str, IMAP_ARG_STR(args));
 		} else if (args->type == IMAP_ARG_STRING) {
-			str_printfa(str, " \"%s\"", args->data.str);
+			str_printfa(str, " \"%s\"", IMAP_ARG_STR(args));
 		} else {
 			return FALSE;
 		}
@@ -560,7 +564,7 @@
 			return FALSE;
 
 		str_append_c(str, ' ');
-		str_append(str, args->data.str);
+		str_append(str, IMAP_ARG_STR(args));
 	} else if (message_rfc822) {
 		/* message/rfc822 - envelope + bodystructure + text lines */
 		if (args[0].type != IMAP_ARG_LIST ||
@@ -570,17 +574,18 @@
 
 		str_append_c(str, ' ');
 
-		if (!imap_write_list(args[0].data.list->args, str))
+		list = IMAP_ARG_LIST(&args[0]);
+		if (!imap_write_list(list->args, str))
 			return FALSE;
 
 		str_append_c(str, ' ');
 
-		if (!imap_parse_bodystructure_args(args[1].data.list->args,
-						   str))
+		list = IMAP_ARG_LIST(&args[1]);
+		if (!imap_parse_bodystructure_args(list->args, str))
 			return FALSE;
 
 		str_append_c(str, ' ');
-		str_append(str, args[2].data.str);
+		str_append(str, IMAP_ARG_STR(&args[2]));
 	}
 
 	return TRUE;

Index: imap-envelope.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-imap/imap-envelope.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- imap-envelope.c	21 Dec 2002 22:02:58 -0000	1.17
+++ imap-envelope.c	2 Jan 2003 08:09:27 -0000	1.18
@@ -128,7 +128,7 @@
 
 	if (arg->type != IMAP_ARG_LIST)
 		return FALSE;
-	list = arg->data.list;
+	list = IMAP_ARG_LIST(arg);
 
 	/* we require 4 arguments, strings or NILs */
 	if (list->size < 4)
@@ -137,8 +137,9 @@
 	for (i = 0; i < 4; i++) {
 		if (list->args[i].type == IMAP_ARG_NIL)
 			args[i] = NULL;
-		else if (list->args[i].type == IMAP_ARG_STRING)
-			args[i] = list->args[i].data.str;
+		else if (list->args[i].type == IMAP_ARG_STRING ||
+			 list->args[i].type == IMAP_ARG_ATOM)
+			args[i] = IMAP_ARG_STR(&list->args[i]);
 		else
 			return FALSE;
 	}
@@ -200,7 +201,7 @@
 	in_group = FALSE;
 	str = t_str_new(128);
 
-        list = arg->data.list;
+        list = IMAP_ARG_LIST(arg);
 	for (i = 0; i < list->size; i++) {
 		if (!imap_address_arg_append(&list->args[i], str, &in_group))
 			return NULL;
@@ -211,18 +212,25 @@
 
 static const char *imap_envelope_parse_first_mailbox(ImapArg *arg)
 {
+	ImapArgList *list;
+
 	/* ((name route mailbox domain) ...) */
 	if (arg->type != IMAP_ARG_LIST)
 		return NULL;
 
-	if (arg->data.list->size == 0)
+	list = IMAP_ARG_LIST(arg);
+	if (list->size == 0)
 		return "";
 
-	arg = arg->data.list->args;
-	if (arg->type != IMAP_ARG_LIST || arg->data.list->size != 4)
+	arg = IMAP_ARG_LIST(arg)->args;
+	if (arg->type != IMAP_ARG_LIST)
 		return NULL;
 
-	return t_strdup(arg->data.list->args[2].data.str);
+	list = IMAP_ARG_LIST(arg);
+	if (list->size != 4)
+		return NULL;
+
+	return t_strdup(imap_arg_string(&list->args[2]));
 }
 
 static const char *
@@ -238,8 +246,8 @@
 	case IMAP_ENVELOPE_RESULT_STRING:
 		if (field >= IMAP_ENVELOPE_FROM && field <= IMAP_ENVELOPE_BCC)
 			value = imap_envelope_parse_address(arg);
-		else if (arg->type == IMAP_ARG_STRING || arg->type == IMAP_ARG_ATOM)
-			value = t_strdup(arg->data.str);
+		else
+			value = t_strdup(imap_arg_string(arg));
 		break;
 	case IMAP_ENVELOPE_RESULT_FIRST_MAILBOX:
 		i_assert(field >= IMAP_ENVELOPE_FROM &&

Index: imap-parser.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-imap/imap-parser.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- imap-parser.c	21 Dec 2002 13:08:49 -0000	1.27
+++ imap-parser.c	2 Jan 2003 08:09:27 -0000	1.28
@@ -57,7 +57,7 @@
 	if (parser->list_arg == NULL)
 		parser->root_list = parser->cur_list;
 	else
-		parser->list_arg->data.list = parser->cur_list;
+		parser->list_arg->_data.list = parser->cur_list;
 }
 
 ImapParser *imap_parser_create(IStream *input, OStream *output,
@@ -156,7 +156,7 @@
 	imap_args_realloc(parser, LIST_ALLOC_SIZE);
 
 	parser->list_arg->type = IMAP_ARG_LIST;
-	parser->list_arg->data.list = parser->cur_list;
+	parser->list_arg->_data.list = parser->cur_list;
 
 	parser->cur_type = ARG_PARSE_NONE;
 }
@@ -179,7 +179,7 @@
 	if (parser->list_arg == NULL) {
 		parser->cur_list = parser->root_list;
 	} else {
-		parser->cur_list = parser->list_arg->data.list;
+		parser->cur_list = parser->list_arg->_data.list;
 	}
 
 	parser->cur_type = ARG_PARSE_NONE;
@@ -201,7 +201,7 @@
 		} else {
 			/* simply save the string */
 			arg->type = IMAP_ARG_ATOM;
-			arg->data.str = p_strndup(parser->pool, data, lastpos);
+			arg->_data.str = p_strndup(parser->pool, data, lastpos);
 		}
 		break;
 	case ARG_PARSE_STRING:
@@ -209,13 +209,13 @@
 		i_assert(lastpos > 0);
 
 		arg->type = IMAP_ARG_STRING;
-		arg->data.str = p_strndup(parser->pool, data+1, lastpos-1);
+		arg->_data.str = p_strndup(parser->pool, data+1, lastpos-1);
 
 		/* remove the escapes */
 		if (parser->str_first_escape >= 0 &&
 		    (parser->flags & IMAP_PARSE_FLAG_NO_UNESCAPE) == 0) {
 			/* -1 because we skipped the '"' prefix */
-			str_remove_escapes(arg->data.str +
+			str_remove_escapes(arg->_data.str +
 					   parser->str_first_escape-1);
 		}
 		break;
@@ -223,11 +223,11 @@
 		if ((parser->flags & IMAP_PARSE_FLAG_LITERAL_SIZE) == 0) {
 			/* simply save the string */
 			arg->type = IMAP_ARG_STRING;
-			arg->data.str = p_strndup(parser->pool, data, lastpos);
+			arg->_data.str = p_strndup(parser->pool, data, lastpos);
 		} else {
 			/* save literal size */
 			arg->type = IMAP_ARG_LITERAL_SIZE;
-			arg->data.literal_size = parser->literal_size;
+			arg->_data.literal_size = parser->literal_size;
 		}
 		break;
 	default:
@@ -596,9 +596,27 @@
 
 	case IMAP_ARG_ATOM:
 	case IMAP_ARG_STRING:
-		return arg->data.str;
+		return arg->_data.str;
 
 	default:
 		return NULL;
 	}
+}
+
+char *_imap_arg_str_error(const ImapArg *arg)
+{
+	i_panic("Tried to access ImapArg type %d as string", arg->type);
+	return NULL;
+}
+
+uoff_t _imap_arg_literal_size_error(const ImapArg *arg)
+{
+	i_panic("Tried to access ImapArg type %d as literal size", arg->type);
+	return 0;
+}
+
+ImapArgList *_imap_arg_list_error(const ImapArg *arg)
+{
+	i_panic("Tried to access ImapArg type %d as list", arg->type);
+	return NULL;
 }

Index: imap-parser.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-imap/imap-parser.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- imap-parser.h	9 Dec 2002 15:25:20 -0000	1.6
+++ imap-parser.h	2 Jan 2003 08:09:27 -0000	1.7
@@ -33,9 +33,23 @@
 		char *str;
 		uoff_t literal_size;
 		ImapArgList *list;
-	} data;
+	} _data;
 };
 
+#define IMAP_ARG_STR(arg) \
+	((arg)->type == IMAP_ARG_NIL ? NULL : \
+	 (arg)->type == IMAP_ARG_ATOM || (arg)->type == IMAP_ARG_STRING ? \
+	 (arg)->_data.str : _imap_arg_str_error(arg))
+
+#define IMAP_ARG_LITERAL_SIZE(arg) \
+	((arg)->type == IMAP_ARG_LITERAL_SIZE ? \
+	 (arg)->_data.literal_size : _imap_arg_literal_size_error(arg))
+
+#define IMAP_ARG_LIST(arg) \
+	((arg)->type == IMAP_ARG_NIL ? NULL : \
+	 (arg)->type == IMAP_ARG_LIST ? \
+	 (arg)->_data.list : _imap_arg_list_error(arg))
+
 struct _ImapArgList {
 	size_t size, alloc;
 	ImapArg args[1]; /* variable size */
@@ -77,5 +91,10 @@
 
 /* Returns the imap argument as string. NIL returns "" and list returns NULL. */
 const char *imap_arg_string(ImapArg *arg);
+
+/* Error functions */
+char *_imap_arg_str_error(const ImapArg *arg);
+uoff_t _imap_arg_literal_size_error(const ImapArg *arg);
+ImapArgList *_imap_arg_list_error(const ImapArg *arg);
 
 #endif




More information about the dovecot-cvs mailing list