NOTIFY was broken since 2.2.31, and this patch reverts that breakage, using two
upstream commits:

* https://github.com/dovecot/core/commit/bcb321bc62117d30bc53a872ca1154c0100aeefd
* https://github.com/dovecot/core/commit/8b2d740b8182c63b76ff7ef0dd5e01710228705a

From bcb321bc62117d30bc53a872ca1154c0100aeefd Mon Sep 17 00:00:00 2001
From: Timo Sirainen <timo.sirainen@dovecot.fi>
Date: Fri, 30 Jun 2017 17:33:15 +0300
Subject: [PATCH] imap: Fix NOTIFY parameter parsing by reverting earlier
 change

I misread the RFC and wrote broken tests.
Reverts 64d2efdc4b0bdf92249840e9db89b91c8dc0f3a3


From 8b2d740b8182c63b76ff7ef0dd5e01710228705a Mon Sep 17 00:00:00 2001
From: Timo Sirainen <timo.sirainen@dovecot.fi>
Date: Fri, 30 Jun 2017 17:51:34 +0300
Subject: [PATCH] imap: Add more error checking to NOTIFY parameter parsing

This should make it clearer to realize when invalid syntax is being used
rather than just ignoring the problem.


--- src/imap/cmd-notify.c.orig	2017-06-30 21:31:28 UTC
+++ src/imap/cmd-notify.c
@@ -41,6 +41,8 @@ static int
 cmd_notify_parse_fetch(struct imap_notify_context *ctx,
 		       const struct imap_arg *list)
 {
+	if (list->type == IMAP_ARG_EOL)
+		return -1; /* at least one attribute must be set */
 	return imap_fetch_att_list_parse(ctx->client, ctx->pool, list,
 					 &ctx->fetch_ctx, &ctx->error);
 }
@@ -59,11 +61,17 @@ cmd_notify_set_selected(struct imap_noti
 	    strcasecmp(str, "NONE") == 0) {
 		/* no events for selected mailbox. this is also the default
 		   when NOTIFY command doesn't specify it explicitly */
+		if (events[1].type != IMAP_ARG_EOL)
+			return -1; /* no extra parameters */
 		return 0;
 	}
 
 	if (!imap_arg_get_list(events, &list))
 		return -1;
+	if (events[1].type != IMAP_ARG_EOL)
+		return -1; /* no extra parameters */
+	if (list->type == IMAP_ARG_EOL)
+		return -1; /* at least one event */
 
 	for (; list->type != IMAP_ARG_EOL; list++) {
 		if (cmd_notify_parse_event(list, &event) < 0)
@@ -292,10 +300,10 @@ cmd_notify_set(struct imap_notify_contex
 		ctx->send_immediate_status = TRUE;
 		args++;
 	}
+	for (; args->type != IMAP_ARG_EOL; args++) {
+		if (!imap_arg_get_list(args, &event_group))
+			return -1;
 
-	if (!imap_arg_get_list(args, &event_group))
-		return -1;
-	for (; event_group->type != IMAP_ARG_EOL; event_group++) {
 		/* filter-mailboxes */
 		if (!imap_arg_get_atom(event_group, &filter_mailboxes))
 			return -1;
@@ -322,6 +330,15 @@ cmd_notify_set(struct imap_notify_contex
 			if (event_group->type == IMAP_ARG_EOL)
 				return -1;
 			mailboxes = event_group++;
+			/* check that the mailboxes parameter is valid */
+			if (IMAP_ARG_IS_ASTRING(mailboxes))
+				;
+			else if (!imap_arg_get_list(mailboxes, &list))
+				return -1;
+			else if (list->type == IMAP_ARG_EOL) {
+				/* should have at least one mailbox */
+				return -1;
+			}
 		} else {
 			mailboxes = NULL;
 		}
