]> granicus.if.org Git - neomutt/commitdiff
Add mutt_buffer_expand_path()
authorKevin McCarthy <kevin@8t8.us>
Sun, 10 Mar 2019 05:27:11 +0000 (13:27 +0800)
committerRichard Russon <rich@flatcap.org>
Tue, 9 Apr 2019 11:54:28 +0000 (12:54 +0100)
TODO: '@' expansion using mutt_default_save() is still using a fixed size
string parameter.

Convert imap_expand_path() and mutt_rx_sanitize_string() to use
BUFFERS instead.

Add url_ciss_tobuffer().

Co-authored-by: Richard Russon <rich@flatcap.org>
email/url.c
email/url.h
imap/imap.c
imap/imap.h
mutt/file.c
mutt/file.h
muttlib.c
muttlib.h

index 12257bc1695f0b2f5a7e99129df753d6c01cc966..dc543ac83d1eec5cbe3259ddb644034c2727dd14 100644 (file)
@@ -339,56 +339,67 @@ void url_pct_encode(char *buf, size_t buflen, const char *src)
 }
 
 /**
- * url_tostring - Output the URL string for a given Url object
+ * url_tobuffer - Output the URL string for a given Url object
  * @param u      Url to turn into a string
  * @param buf    Buffer for the result
- * @param buflen Length of buffer
  * @param flags  Flags, e.g. #U_PATH
  * @retval  0 Success
  * @retval -1 Error
  */
-int url_tostring(struct Url *u, char *buf, size_t buflen, int flags)
+int url_tobuffer(struct Url *u, struct Buffer *buf, int flags)
 {
   if (u->scheme == U_UNKNOWN)
     return -1;
 
-  snprintf(buf, buflen, "%s:", mutt_map_get_name(u->scheme, UrlMap));
+  mutt_buffer_printf(buf, "%s:", mutt_map_get_name(u->scheme, UrlMap));
 
   if (u->host)
   {
     if (!(flags & U_PATH))
-      mutt_str_strcat(buf, buflen, "//");
-    size_t l = strlen(buf);
-    buflen -= l;
-    buf += l;
+      mutt_buffer_addstr(buf, "//");
 
     if (u->user && (u->user[0] || !(flags & U_PATH)))
     {
       char str[256];
       url_pct_encode(str, sizeof(str), u->user);
-      snprintf(buf, buflen, "%s@", str);
-      l = strlen(buf);
-      buflen -= l;
-      buf += l;
+      mutt_buffer_add_printf(buf, "%s@", str);
     }
 
     if (strchr(u->host, ':'))
-      snprintf(buf, buflen, "[%s]", u->host);
+      mutt_buffer_add_printf(buf, "[%s]", u->host);
     else
-      snprintf(buf, buflen, "%s", u->host);
-
-    l = strlen(buf);
-    buflen -= l;
-    buf += l;
+      mutt_buffer_add_printf(buf, "%s", u->host);
 
     if (u->port)
-      snprintf(buf, buflen, ":%hu/", u->port);
+      mutt_buffer_add_printf(buf, ":%hu/", u->port);
     else
-      snprintf(buf, buflen, "/");
+      mutt_buffer_addstr(buf, "/");
   }
 
   if (u->path)
-    mutt_str_strcat(buf, buflen, u->path);
+    mutt_buffer_addstr(buf, u->path);
 
   return 0;
 }
+
+/**
+ * url_tostring - Output the URL string for a given Url object
+ * @param u      Url to turn into a string
+ * @param dest   Buffer for the result
+ * @param len    Length of buffer
+ * @param flags  Flags, e.g. #U_PATH
+ * @retval  0 Success
+ * @retval -1 Error
+ */
+int url_tostring(struct Url *u, char *dest, size_t len, int flags)
+{
+  struct Buffer *dest_buf = mutt_buffer_pool_get();
+
+  int retval = url_tobuffer(u, dest_buf, flags);
+  if (retval == 0)
+    mutt_str_strfcpy(dest, mutt_b2s(dest_buf), len);
+
+  mutt_buffer_pool_release(&dest_buf);
+
+  return retval;
+}
index 40d122ddb28ec51b102df07ee8d2ab7a29012999..9d8b4de9d4fd06fae037b71c02271d5c6ddaa4d7 100644 (file)
@@ -81,6 +81,7 @@ void           url_free(struct Url **u);
 struct Url    *url_parse(const char *src);
 int            url_pct_decode(char *s);
 void           url_pct_encode(char *buf, size_t buflen, const char *src);
+int            url_tobuffer(struct Url *u, struct Buffer *dest, int flags);
 int            url_tostring(struct Url *u, char *buf, size_t buflen, int flags);
 
 #endif /* MUTT_EMAIL_URL_H */
index d67100e1d0920d8cd948c0ea221d76de3354639f..c9c97454eaee033bf9e6c82bc22030d3d74f350f 100644 (file)
@@ -2490,6 +2490,20 @@ int imap_path_canon(char *buf, size_t buflen)
   return 0;
 }
 
+/**
+ * imap_expand_path - Buffer wrapper around imap_path_canon()
+ * @param buf Path to expand 
+ * @retval  0 Success
+ * @retval -1 Failure
+ *
+ * @note The path is expanded in place
+ */
+int imap_expand_path(struct Buffer *buf)
+{
+  mutt_buffer_increase_size(buf, PATH_MAX);
+  return imap_path_canon(buf->data, PATH_MAX);
+}
+
 /**
  * imap_path_pretty - Implements MxOps::path_pretty()
  */
index fa55eb700a1806093d6d0a0b728b164d7ab99a17..7bd45e0b7fba1cc2dda4792454e857b08862aa14 100644 (file)
@@ -105,6 +105,7 @@ int imap_copy_messages(struct Mailbox *m, struct EmailList *el, char *dest, bool
 void imap_logout_all(void);
 
 /* util.c */
+int imap_expand_path(struct Buffer *buf);
 int imap_parse_path(const char *path, struct ConnAccount *account, char *mailbox, size_t mailboxlen);
 void imap_pretty_mailbox(char *path, size_t pathlen, const char *folder);
 
index e2fd5bae3bb501ec27188391639809ef8e0606ff..6b8a6224c2b402220b635e5b19e64eaf1eb8f6a4 100644 (file)
@@ -42,6 +42,7 @@
 #include <unistd.h>
 #include <utime.h>
 #include "file.h"
+#include "buffer.h"
 #include "logging.h"
 #include "memory.h"
 #include "message.h"
@@ -587,30 +588,22 @@ void mutt_file_sanitize_filename(char *fp, bool slash)
 
 /**
  * mutt_file_sanitize_regex - Escape any regex-magic characters in a string
- * @param dest    Buffer for result
- * @param destlen Length of buffer
- * @param src     String to transform
+ * @param dest Buffer for result
+ * @param src  String to transform
  * @retval  0 Success
  * @retval -1 Error
  */
-int mutt_file_sanitize_regex(char *dest, size_t destlen, const char *src)
+int mutt_file_sanitize_regex(struct Buffer *dest, const char *src)
 {
-  while (*src && (--destlen > 2))
+  mutt_buffer_reset(dest);
+  while (*src != '\0')
   {
     if (strchr(rx_special_chars, *src))
-    {
-      *dest++ = '\\';
-      destlen--;
-    }
-    *dest++ = *src++;
+      mutt_buffer_addch(dest, '\\');
+    mutt_buffer_addch(dest, *src++);
   }
 
-  *dest = '\0';
-
-  if (*src)
-    return -1;
-  else
-    return 0;
+  return 0;
 }
 
 /**
index 50ff76c2118dad0bfd0b4dbc6ef87b7c8c4e6487..09bf95e5921c47973b8bf4b9cdd260807dc8549f 100644 (file)
@@ -29,6 +29,7 @@
 #include <sys/types.h>
 #include <time.h>
 
+struct Buffer;
 struct stat;
 extern char *C_Tmpdir;
 
@@ -109,7 +110,7 @@ int         mutt_file_rename(const char *oldfile, const char *newfile);
 int         mutt_file_rmtree(const char *path);
 int         mutt_file_safe_rename(const char *src, const char *target);
 void        mutt_file_sanitize_filename(char *fp, bool slash);
-int         mutt_file_sanitize_regex(char *dest, size_t destlen, const char *src);
+int         mutt_file_sanitize_regex(struct Buffer *dest, const char *src);
 void        mutt_file_set_mtime(const char *from, const char *to);
 int         mutt_file_stat_compare(struct stat *sba, enum MuttStatType sba_type, struct stat *sbb, enum MuttStatType sbb_type);
 int         mutt_file_stat_timespec_compare(struct stat *sba, enum MuttStatType type, struct timespec *b);
index 7ed72108851a3400e2acba9740483fbb3b6b9169..5bc19dfafee6cf4be0b585aa419b136dbb4aa27b 100644 (file)
--- a/muttlib.c
+++ b/muttlib.c
@@ -160,47 +160,47 @@ char *mutt_expand_path(char *buf, size_t buflen)
 }
 
 /**
- * mutt_expand_path_regex - Create the canonical path (with regex char escaping)
+ * mutt_buffer_expand_path - Create the canonical path (with regex char escaping)
  * @param buf     Buffer with path
- * @param buflen  Length of buffer
  * @param regex If true, escape any regex characters
- * @retval ptr The expanded string
  *
  * @note The path is expanded in-place
  */
-char *mutt_expand_path_regex(char *buf, size_t buflen, bool regex)
+void mutt_buffer_expand_path(struct Buffer *buf, bool regex)
 {
-  char p[PATH_MAX] = "";
-  char q[PATH_MAX] = "";
-  char tmp[PATH_MAX];
-
+  const char *s = NULL;
   const char *tail = "";
 
   bool recurse = false;
 
+  struct Buffer *p = mutt_buffer_pool_get();
+  struct Buffer *q = mutt_buffer_pool_get();
+  struct Buffer *tmp = mutt_buffer_pool_get();
+
   do
   {
     recurse = false;
+    s = buf->data;
 
-    switch (*buf)
+    switch (*s)
     {
       case '~':
       {
-        if ((*(buf + 1) == '/') || (*(buf + 1) == 0))
+        if ((*(s + 1) == '/') || (*(s + 1) == 0))
         {
-          mutt_str_strfcpy(p, HomeDir, sizeof(p));
-          tail = buf + 1;
+          mutt_buffer_strcpy(p, HomeDir);
+          tail = s + 1;
         }
         else
         {
-          char *t = strchr(buf + 1, '/');
+          char *t = strchr(s + 1, '/');
           if (t)
             *t = '\0';
 
-          struct passwd *pw = getpwnam(buf + 1);
+          struct passwd *pw = getpwnam(s + 1);
           if (pw)
           {
-            mutt_str_strfcpy(p, pw->pw_dir, sizeof(p));
+            mutt_buffer_strcpy(p, pw->pw_dir);
             if (t)
             {
               *t = '/';
@@ -214,8 +214,8 @@ char *mutt_expand_path_regex(char *buf, size_t buflen, bool regex)
             /* user not found! */
             if (t)
               *t = '/';
-            *p = '\0';
-            tail = buf;
+            mutt_buffer_reset(p);
+            tail = s;
           }
         }
         break;
@@ -230,16 +230,16 @@ char *mutt_expand_path_regex(char *buf, size_t buflen, bool regex)
         if ((mb_type == MUTT_IMAP) && ((C_Folder[strlen(C_Folder) - 1] == '}') ||
                                        (C_Folder[strlen(C_Folder) - 1] == '/')))
         {
-          mutt_str_strfcpy(p, C_Folder, sizeof(p));
+          mutt_buffer_strcpy(p, NONULL(C_Folder));
         }
         else if (mb_type == MUTT_NOTMUCH)
-          mutt_str_strfcpy(p, C_Folder, sizeof(p));
+          mutt_buffer_strcpy(p, NONULL(C_Folder));
         else if (C_Folder && *C_Folder && (C_Folder[strlen(C_Folder) - 1] == '/'))
-          mutt_str_strfcpy(p, C_Folder, sizeof(p));
+          mutt_buffer_strcpy(p, NONULL(C_Folder));
         else
-          snprintf(p, sizeof(p), "%s/", NONULL(C_Folder));
+          mutt_buffer_printf(p, "%s/", NONULL(C_Folder));
 
-        tail = buf + 1;
+        tail = s + 1;
         break;
       }
 
@@ -247,19 +247,24 @@ char *mutt_expand_path_regex(char *buf, size_t buflen, bool regex)
 
       case '@':
       {
-        struct Address *alias = mutt_alias_lookup(buf + 1);
+        struct Address *alias = mutt_alias_lookup(s + 1);
         if (alias)
         {
           struct Email *e = mutt_email_new();
           e->env = mutt_env_new();
           e->env->from = alias;
           e->env->to = alias;
-          mutt_default_save(p, sizeof(p), e);
+
+          /* TODO: fix mutt_default_save() to use Buffer */
+          mutt_buffer_increase_size(p, PATH_MAX);
+          mutt_default_save(p->data, p->dsize, e);
+          mutt_buffer_fix_dptr(p);
+
           e->env->from = NULL;
           e->env->to = NULL;
           mutt_email_free(&e);
           /* Avoid infinite recursion if the resulting folder starts with '@' */
-          if (*p != '@')
+          if (*(p->data) != '@')
             recurse = true;
 
           tail = "";
@@ -269,71 +274,95 @@ char *mutt_expand_path_regex(char *buf, size_t buflen, bool regex)
 
       case '>':
       {
-        mutt_str_strfcpy(p, C_Mbox, sizeof(p));
-        tail = buf + 1;
+        mutt_buffer_strcpy(p, C_Mbox);
+        tail = s + 1;
         break;
       }
 
       case '<':
       {
-        mutt_str_strfcpy(p, C_Record, sizeof(p));
-        tail = buf + 1;
+        mutt_buffer_strcpy(p, C_Record);
+        tail = s + 1;
         break;
       }
 
       case '!':
       {
-        if (*(buf + 1) == '!')
+        if (*(s + 1) == '!')
         {
-          mutt_str_strfcpy(p, LastFolder, sizeof(p));
-          tail = buf + 2;
+          mutt_buffer_strcpy(p, LastFolder);
+          tail = s + 2;
         }
         else
         {
-          mutt_str_strfcpy(p, C_Spoolfile, sizeof(p));
-          tail = buf + 1;
+          mutt_buffer_strcpy(p, C_Spoolfile);
+          tail = s + 1;
         }
         break;
       }
 
       case '-':
       {
-        mutt_str_strfcpy(p, LastFolder, sizeof(p));
-        tail = buf + 1;
+        mutt_buffer_strcpy(p, LastFolder);
+        tail = s + 1;
         break;
       }
 
       case '^':
       {
-        mutt_str_strfcpy(p, CurrentFolder, sizeof(p));
-        tail = buf + 1;
+        mutt_buffer_strcpy(p, CurrentFolder);
+        tail = s + 1;
         break;
       }
 
       default:
       {
-        *p = '\0';
-        tail = buf;
+        mutt_buffer_reset(p);
+        tail = s;
       }
     }
 
-    if (regex && *p && !recurse)
+    if (regex && *p->data && !recurse)
     {
-      mutt_file_sanitize_regex(q, sizeof(q), p);
-      snprintf(tmp, sizeof(tmp), "%s%s", q, tail);
+      mutt_file_sanitize_regex(q, mutt_b2s(p));
+      mutt_buffer_printf(tmp, "%s%s", mutt_b2s(q), tail);
     }
     else
-      snprintf(tmp, sizeof(tmp), "%s%s", p, tail);
+      mutt_buffer_printf(tmp, "%s%s", mutt_b2s(p), tail);
 
-    mutt_str_strfcpy(buf, tmp, buflen);
+    mutt_buffer_strcpy(buf, mutt_b2s(tmp));
   } while (recurse);
 
+  mutt_buffer_pool_release(&p);
+  mutt_buffer_pool_release(&q);
+  mutt_buffer_pool_release(&tmp);
+
 #ifdef USE_IMAP
   /* Rewrite IMAP path in canonical form - aids in string comparisons of
    * folders. May possibly fail, in which case buf should be the same. */
-  if (imap_path_probe(buf, NULL) == MUTT_IMAP)
-    imap_path_canon(buf, buflen);
+  if (imap_path_probe(mutt_b2s(buf), NULL) == MUTT_IMAP)
+    imap_expand_path(buf);
 #endif
+}
+
+/**
+ * mutt_expand_path_regex - Create the canonical path (with regex char escaping)
+ * @param buf     Buffer with path
+ * @param buflen  Length of buffer
+ * @param regex If true, escape any regex characters
+ * @retval ptr The expanded string
+ *
+ * @note The path is expanded in-place
+ */
+char *mutt_expand_path_regex(char *buf, size_t buflen, bool regex)
+{
+  struct Buffer *tmp = mutt_buffer_pool_get();
+
+  mutt_buffer_addstr(tmp, buf);
+  mutt_buffer_expand_path(tmp, regex);
+  mutt_str_strfcpy(buf, mutt_b2s(tmp), buflen);
+
+  mutt_buffer_pool_release(&tmp);
 
   return buf;
 }
index e062330fc303130c76ef63084310d9797baeb5d0..67b2d9abe636e058f2c668ff4e0621a24e4e4c4b 100644 (file)
--- a/muttlib.h
+++ b/muttlib.h
@@ -45,11 +45,12 @@ extern struct Regex *C_GecosMask;
 void        mutt_adv_mktemp(char *s, size_t l);
 void        mutt_buffer_adv_mktemp (struct Buffer *buf);
 void        mutt_buffer_mktemp_full(struct Buffer *buf, const char *prefix, const char *suffix, const char *src, int line);
+void        mutt_buffer_expand_path(struct Buffer *buf, bool regex);
 int         mutt_check_overwrite(const char *attname, const char *path, char *fname, size_t flen, enum SaveAttach *opt, char **directory);
 void        mutt_encode_path(char *dest, size_t dlen, const char *src);
 void        mutt_expando_format(char *buf, size_t buflen, size_t col, int cols, const char *src, format_t *callback, unsigned long data, MuttFormatFlags flags);
 char *      mutt_expand_path(char *s, size_t slen);
-char *      mutt_expand_path_regex(char *s, size_t slen, bool regex);
+char *      mutt_expand_path_regex(char *buf, size_t buflen, bool regex);
 char *      mutt_gecos_name(char *dest, size_t destlen, struct passwd *pw);
 void        mutt_get_parent_path(char *path, char *buf, size_t buflen);
 int         mutt_inbox_cmp(const char *a, const char *b);