]> granicus.if.org Git - neomutt/commitdiff
Convert mutt_parse_hook() to use buffer pool
authorKevin McCarthy <kevin@8t8.us>
Sun, 6 Oct 2019 05:37:14 +0000 (13:37 +0800)
committerRichard Russon <rich@flatcap.org>
Sat, 26 Oct 2019 22:55:43 +0000 (23:55 +0100)
Remove the path variable, as this is not needed:
mutt_buffer_expand_path() and mutt_check_simple() can operate directly
on the pattern/command buffers.

Upstream-commit: https://gitlab.com/muttmua/mutt/commit/8351c060aa3be2ec0c14a26a0d9dcb5a15203512
Co-authored-by: Richard Russon <rich@flatcap.org>
hook.c

diff --git a/hook.c b/hook.c
index 272de0bd92cbad56c6b1196069f481c7a7895dba..5cf51435c5505794d62f72287bff3bb09d588cf2 100644 (file)
--- a/hook.c
+++ b/hook.c
@@ -86,15 +86,13 @@ enum CommandResult mutt_parse_hook(struct Buffer *buf, struct Buffer *s,
                                    unsigned long data, struct Buffer *err)
 {
   struct Hook *hook = NULL;
-  struct Buffer cmd, pattern;
-  int rc;
-  bool pat_not = false, warning = false;
+  int rc = MUTT_CMD_ERROR;
+  bool pat_not = false;
   regex_t *rx = NULL;
   struct PatternList *pat = NULL;
-  char path[PATH_MAX];
 
-  mutt_buffer_init(&pattern);
-  mutt_buffer_init(&cmd);
+  struct Buffer *cmd = mutt_buffer_pool_get();
+  struct Buffer *pattern = mutt_buffer_pool_get();
 
   if (~data & MUTT_GLOBAL_HOOK) /* NOT a global hook */
   {
@@ -105,65 +103,69 @@ enum CommandResult mutt_parse_hook(struct Buffer *buf, struct Buffer *s,
       pat_not = true;
     }
 
-    mutt_extract_token(&pattern, s, MUTT_TOKEN_NO_FLAGS);
+    mutt_extract_token(pattern, s, MUTT_TOKEN_NO_FLAGS);
 
     if (!MoreArgs(s))
     {
       mutt_buffer_printf(err, _("%s: too few arguments"), buf->data);
-      goto warn;
+      rc = MUTT_CMD_WARNING;
+      goto cleanup;
     }
   }
 
-  mutt_extract_token(&cmd, s,
+  mutt_extract_token(cmd, s,
                      (data & (MUTT_FOLDER_HOOK | MUTT_SEND_HOOK | MUTT_SEND2_HOOK |
                               MUTT_ACCOUNT_HOOK | MUTT_REPLY_HOOK)) ?
                          MUTT_TOKEN_SPACE :
                          MUTT_TOKEN_NO_FLAGS);
 
-  if (!cmd.data)
+  if (mutt_buffer_is_empty(cmd))
   {
     mutt_buffer_printf(err, _("%s: too few arguments"), buf->data);
-    goto warn;
+    rc = MUTT_CMD_WARNING;
+    goto cleanup;
   }
 
   if (MoreArgs(s))
   {
     mutt_buffer_printf(err, _("%s: too many arguments"), buf->data);
-    goto warn;
+    rc = MUTT_CMD_WARNING;
+    goto cleanup;
   }
 
   if (data & (MUTT_FOLDER_HOOK | MUTT_MBOX_HOOK))
   {
     /* Accidentally using the ^ mailbox shortcut in the .neomuttrc is a
      * common mistake */
-    if ((*pattern.data == '^') && (!CurrentFolder))
+    if ((pattern->data[0] == '^') && !CurrentFolder)
     {
       mutt_buffer_strcpy(err, _("current mailbox shortcut '^' is unset"));
-      goto error;
+      goto cleanup;
     }
 
-    mutt_str_strfcpy(path, pattern.data, sizeof(path));
-    mutt_expand_path_regex(path, sizeof(path), true);
+    struct Buffer *tmp = mutt_buffer_pool_get();
+    mutt_buffer_strcpy(tmp, mutt_b2s(pattern));
+    mutt_buffer_expand_path_regex(tmp, true);
 
     /* Check for other mailbox shortcuts that expand to the empty string.
      * This is likely a mistake too */
-    if (!*path && *pattern.data)
+    if (mutt_buffer_is_empty(tmp) && !mutt_buffer_is_empty(pattern))
     {
       mutt_buffer_strcpy(err, _("mailbox shortcut expanded to empty regex"));
-      goto error;
+      mutt_buffer_pool_release(&tmp);
+      goto cleanup;
     }
 
-    FREE(&pattern.data);
-    mutt_buffer_init(&pattern);
-    pattern.data = mutt_str_strdup(path);
+    mutt_buffer_strcpy(pattern, mutt_b2s(tmp));
+    mutt_buffer_pool_release(&tmp);
   }
 #ifdef USE_COMPRESSED
   else if (data & (MUTT_APPEND_HOOK | MUTT_OPEN_HOOK | MUTT_CLOSE_HOOK))
   {
-    if (mutt_comp_valid_command(cmd.data) == 0)
+    if (mutt_comp_valid_command(mutt_b2s(cmd)) == 0)
     {
       mutt_buffer_strcpy(err, _("badly formatted command string"));
-      return MUTT_CMD_ERROR;
+      goto cleanup;
     }
   }
 #endif
@@ -171,26 +173,15 @@ enum CommandResult mutt_parse_hook(struct Buffer *buf, struct Buffer *s,
            !(data & (MUTT_CHARSET_HOOK | MUTT_ICONV_HOOK | MUTT_ACCOUNT_HOOK)) &&
            (!WithCrypto || !(data & MUTT_CRYPT_HOOK)))
   {
-    struct Buffer *tmp = mutt_buffer_pool_get();
-
     /* At this stage remain only message-hooks, reply-hooks, send-hooks,
      * send2-hooks, save-hooks, and fcc-hooks: All those allowing full
      * patterns. If given a simple regex, we expand $default_hook.  */
-    mutt_buffer_strcpy(tmp, pattern.data);
-    mutt_check_simple(tmp, C_DefaultHook);
-    FREE(&pattern.data);
-    mutt_buffer_init(&pattern);
-    pattern.data = mutt_str_strdup(mutt_b2s(tmp));
-    mutt_buffer_pool_release(&tmp);
+    mutt_check_simple(pattern, C_DefaultHook);
   }
 
   if (data & (MUTT_MBOX_HOOK | MUTT_SAVE_HOOK | MUTT_FCC_HOOK))
   {
-    mutt_str_strfcpy(path, cmd.data, sizeof(path));
-    mutt_expand_path(path, sizeof(path));
-    FREE(&cmd.data);
-    mutt_buffer_init(&cmd);
-    cmd.data = mutt_str_strdup(path);
+    mutt_buffer_expand_path(cmd);
   }
 
   /* check to make sure that a matching hook doesn't already exist */
@@ -199,14 +190,14 @@ enum CommandResult mutt_parse_hook(struct Buffer *buf, struct Buffer *s,
     if (data & MUTT_GLOBAL_HOOK)
     {
       /* Ignore duplicate global hooks */
-      if (mutt_str_strcmp(hook->command, cmd.data) == 0)
+      if (mutt_str_strcmp(hook->command, mutt_b2s(cmd)) == 0)
       {
-        FREE(&cmd.data);
-        return MUTT_CMD_SUCCESS;
+        rc = MUTT_CMD_SUCCESS;
+        goto cleanup;
       }
     }
     else if ((hook->type == data) && (hook->regex.pat_not == pat_not) &&
-             (mutt_str_strcmp(pattern.data, hook->regex.pattern) == 0))
+             (mutt_str_strcmp(mutt_b2s(pattern), hook->regex.pattern) == 0))
     {
       if (data & (MUTT_FOLDER_HOOK | MUTT_SEND_HOOK | MUTT_SEND2_HOOK | MUTT_MESSAGE_HOOK |
                   MUTT_ACCOUNT_HOOK | MUTT_REPLY_HOOK | MUTT_CRYPT_HOOK |
@@ -215,11 +206,10 @@ enum CommandResult mutt_parse_hook(struct Buffer *buf, struct Buffer *s,
         /* these hooks allow multiple commands with the same
          * pattern, so if we've already seen this pattern/command pair, just
          * ignore it instead of creating a duplicate */
-        if (mutt_str_strcmp(hook->command, cmd.data) == 0)
+        if (mutt_str_strcmp(hook->command, mutt_b2s(cmd)) == 0)
         {
-          FREE(&cmd.data);
-          FREE(&pattern.data);
-          return MUTT_CMD_SUCCESS;
+          rc = MUTT_CMD_SUCCESS;
+          goto cleanup;
         }
       }
       else
@@ -230,9 +220,9 @@ enum CommandResult mutt_parse_hook(struct Buffer *buf, struct Buffer *s,
          * a common action to perform is to change the default (.) entry
          * based upon some other information. */
         FREE(&hook->command);
-        hook->command = cmd.data;
-        FREE(&pattern.data);
-        return MUTT_CMD_SUCCESS;
+        hook->command = mutt_str_strdup(mutt_b2s(cmd));
+        rc = MUTT_CMD_SUCCESS;
+        goto cleanup;
       }
     }
   }
@@ -241,53 +231,49 @@ enum CommandResult mutt_parse_hook(struct Buffer *buf, struct Buffer *s,
   {
     /* These are managed separately by the charset code */
     enum LookupType type = (data & MUTT_CHARSET_HOOK) ? MUTT_LOOKUP_CHARSET : MUTT_LOOKUP_ICONV;
-    if (!mutt_ch_lookup_add(type, pattern.data, cmd.data, err))
-      goto error;
-    FREE(&pattern.data);
-    FREE(&cmd.data);
-    return MUTT_CMD_SUCCESS;
+    if (mutt_ch_lookup_add(type, mutt_b2s(pattern), mutt_b2s(cmd), err))
+      rc = MUTT_CMD_SUCCESS;
+    goto cleanup;
   }
   else if (data & (MUTT_SEND_HOOK | MUTT_SEND2_HOOK | MUTT_SAVE_HOOK |
                    MUTT_FCC_HOOK | MUTT_MESSAGE_HOOK | MUTT_REPLY_HOOK))
   {
-    pat = mutt_pattern_comp(pattern.data,
+    pat = mutt_pattern_comp(mutt_b2s(pattern),
                             (data & (MUTT_SEND_HOOK | MUTT_SEND2_HOOK | MUTT_FCC_HOOK)) ?
                                 MUTT_PC_NO_FLAGS :
                                 MUTT_PC_FULL_MSG,
                             err);
     if (!pat)
-      goto error;
+      goto cleanup;
   }
   else if (~data & MUTT_GLOBAL_HOOK) /* NOT a global hook */
   {
     /* Hooks not allowing full patterns: Check syntax of regex */
     rx = mutt_mem_malloc(sizeof(regex_t));
-    rc = REG_COMP(rx, NONULL(pattern.data), ((data & MUTT_CRYPT_HOOK) ? REG_ICASE : 0));
-    if (rc != 0)
+    int rc2 = REG_COMP(rx, NONULL(mutt_b2s(pattern)),
+                       ((data & MUTT_CRYPT_HOOK) ? REG_ICASE : 0));
+    if (rc2 != 0)
     {
-      regerror(rc, rx, err->data, err->dsize);
+      regerror(rc2, rx, err->data, err->dsize);
       FREE(&rx);
-      goto error;
+      goto cleanup;
     }
   }
 
   hook = mutt_mem_calloc(1, sizeof(struct Hook));
   hook->type = data;
-  hook->command = cmd.data;
+  hook->command = mutt_str_strdup(mutt_b2s(cmd));
   hook->pattern = pat;
-  hook->regex.pattern = pattern.data;
+  hook->regex.pattern = mutt_str_strdup(mutt_b2s(pattern));
   hook->regex.regex = rx;
   hook->regex.pat_not = pat_not;
   TAILQ_INSERT_TAIL(&Hooks, hook, entries);
-  return MUTT_CMD_SUCCESS;
+  rc = MUTT_CMD_SUCCESS;
 
-warn:
-  warning = true;
-error:
-  if (~data & MUTT_GLOBAL_HOOK) /* NOT a global hook */
-    FREE(&pattern.data);
-  FREE(&cmd.data);
-  return (warning ? MUTT_CMD_WARNING : MUTT_CMD_ERROR);
+cleanup:
+  mutt_buffer_pool_release(&cmd);
+  mutt_buffer_pool_release(&pattern);
+  return rc;
 }
 
 /**