The query_command option expects the command to return lines in the
following format:
<email address> <tab> <long name> <tab> <other info> <newline>

(From https://gitlab.com/muttmua/mutt/-/wikis/MuttGuide/Aliases)

Before this patch the parser used strtok() to iterate through the Tab
separators. The problem is that strtok() skips through multiple
consecutive Tab characters at once. This imposed a hidden requirement on
the format above, which is that <long name> must not be empty, otherwise
the parser will have a weird bug, where it will interpret the <other
info> token as the <long name> token, because it consumed two
consecutive Tab separators in one call.

To fix this, we replace strtok() with strsep() which is almost
identical, except that it does not skip over consecutive tokens,
therefore the above usecase scenario will work as expected, i.e. <long
name> will be an empty string and <other info> will be the correct
token.

This allows us to provide <other info> while still leaving out the <long
name> token which fixes #397.

Example:
Program outputs: f...@bar.com\t\tOther Info\n
Before this patch: <long name> = "Other Info", <other info> = ""
After this patch: <long name> = "", <other info> = "Other Info"

This would mean that before this patch, in the query_command menu, mutt
would insert "Other Info <f...@bar.com>" by mistake, whereas now it will
correctly insert "<f...@bar.com>".

Signed-off-by: Magnus Groß <magnus.gr...@rwth-aachen.de>
---
 query.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/query.c b/query.c
index 5a5c07b0..5533ddc1 100644
--- a/query.c
+++ b/query.c
@@ -128,7 +128,7 @@ static QUERY *run_query (char *s, int quiet)
   msg = mutt_read_line (msg, &msglen, fp, &dummy, 0);
   while ((buf = mutt_read_line (buf, &buflen, fp, &dummy, 0)) != NULL)
   {
-    if ((p = strtok(buf, "\t\n")))
+    if ((p = strsep(&buf, "\t\n")))
     {
       if (first == NULL)
       {
@@ -142,11 +142,11 @@ static QUERY *run_query (char *s, int quiet)
       }
 
       cur->addr = rfc822_parse_adrlist (cur->addr, p);
-      p = strtok(NULL, "\t\n");
+      p = strsep(&buf, "\t\n");
       if (p)
       {
        cur->name = safe_strdup (p);
-       p = strtok(NULL, "\t\n");
+       p = strsep(&buf, "\t\n");
        if (p)
          cur->other = safe_strdup (p);
       }
-- 
2.35.1

Reply via email to