File 0002-Fixed-GETMETADATA-parsing.patch of Package cyrus-imapd-3

From 9a27d175b594f5315437ad7701f87bb643ec82fc Mon Sep 17 00:00:00 2001
From: Christian Mollekopf <mollekopf@apheleia-it.ch>
Date: Thu, 18 May 2023 14:52:04 +0200
Subject: [PATCH 2/2] Fixed GETMETADATA parsing

THe previous implementation broken when requesting multiple metadata
items (/shared/vendor/foo /private/vendor/foo).
I assume this breaks GETANNOTATION and it may not work in the cases that
the parsing in imap.c handles, but at least the basics work.
---
 imap/imap_proxy.c | 34 +++++++++++++++++++---------------
 1 file changed, 19 insertions(+), 15 deletions(-)

diff --git a/imap/imap_proxy.c b/imap/imap_proxy.c
index 14de79732..4e0db8821 100644
--- a/imap/imap_proxy.c
+++ b/imap/imap_proxy.c
@@ -1409,7 +1409,7 @@ int annotate_fetch_proxy(const char *server, const char *mbox_pat,
                          const strarray_t *attribute_pat)
 {
     struct backend *be;
-    int i, j;
+    int i;
     char mytag[128];
 
     assert(server && mbox_pat && entry_pat && attribute_pat);
@@ -1422,24 +1422,28 @@ int annotate_fetch_proxy(const char *server, const char *mbox_pat,
     /* Send command to remote */
     proxy_gentag(mytag, sizeof(mytag));
     prot_printf(be->out, "%s GETMETADATA \"%s\" (", mytag, mbox_pat);
+
+    if (entry_pat->count != attribute_pat->count) {
+        syslog(LOG_ERR, "Number of scopes and entries must match");
+        return IMAP_INTERNAL;
+    }
+
     for (i = 0; i < entry_pat->count; i++) {
         const char *entry = strarray_nth(entry_pat, i);
-
-        for (j = 0; j < attribute_pat->count; j++) {
-            const char *scope, *attr = strarray_nth(attribute_pat, j);
-            if (!strcmp(attr, "value.shared")) {
-                scope = "/shared";
-            }
-            else if (!strcmp(attr, "value.priv")) {
-                scope = "/private";
-            }
-            else {
-                syslog(LOG_ERR, "won't get deprecated annotation attribute %s", attr);
-                continue;
-            }
-            prot_printf(be->out, "%s%s%s", i ? " " : "", scope, entry);
+        const char *scope, *attr = strarray_nth(attribute_pat, i);
+        if (!strcmp(attr, "value.shared")) {
+            scope = "/shared";
         }
+        else if (!strcmp(attr, "value.priv")) {
+            scope = "/private";
+        }
+        else {
+            syslog(LOG_ERR, "won't get deprecated annotation attribute %s", attr);
+            continue;
+        }
+        prot_printf(be->out, "%s%s%s", i ? " " : "", scope, entry);
     }
+
     prot_printf(be->out, ")\r\n");
     prot_flush(be->out);
 
-- 
2.40.0