]> granicus.if.org Git - neomutt/commitdiff
Make sure paths created by header/body/news cache are POSIX-compliant (#1080)
authorPietro Cerutti <gahr@gahr.ch>
Wed, 14 Mar 2018 11:27:30 +0000 (11:27 +0000)
committerGitHub <noreply@github.com>
Wed, 14 Mar 2018 11:27:30 +0000 (11:27 +0000)
* Make sure paths created by header/body cache are POSIX-compliant

Issue #1073

* Make sure single-file header cache is sanitized

Issue #1073

* Avoid double path normalization

Issue #1073

* Make sure bcache_path works for a NULL mailbox (see POP)

Issue #1073

* Encode news cache dir path

Issue #1073

bcache.c
hcache/hcache.c
muttlib.c
newsrc.c

index 719415389ad6a673a8e61c706a7fbfbdc620b009..966a5cf9dd7893606f914c02fdfedaa91d5163e6 100644 (file)
--- a/bcache.c
+++ b/bcache.c
@@ -49,7 +49,6 @@ struct BodyCache
 static int bcache_path(struct Account *account, const char *mailbox, char *dst, size_t dstlen)
 {
   char host[STRING];
-  char path[_POSIX_PATH_MAX];
   struct Url url;
   int len;
 
@@ -70,14 +69,12 @@ static int bcache_path(struct Account *account, const char *mailbox, char *dst,
     return -1;
   }
 
-  mutt_encode_path(path, sizeof(path), NONULL(mailbox));
-
-  int plen = mutt_str_strlen(path);
-  if (plen == 0)
-    return -1;
+  size_t mailboxlen = mutt_str_strlen(mailbox);
+  len = snprintf(dst, dstlen - 1, "%s/%s%s%s", MessageCachedir, host,
+                 NONULL(mailbox),
+                 (mailboxlen != 0 && mailbox[mailboxlen - 1] == '/') ? "" : "/");
 
-  len = snprintf(dst, dstlen - 1, "%s/%s%s%s", MessageCachedir, host, path,
-                 (*path && path[plen - 1] == '/') ? "" : "/");
+  mutt_encode_path(dst, dstlen, dst);
 
   mutt_debug(3, "rc: %d, path: '%s'\n", len, dst);
 
index 4b0a4696005bd4724005a46e452eeb6b391c9653..606ffd1a3dc22c1af3d562d61c115319376a4d31 100644 (file)
@@ -585,6 +585,7 @@ static const char *hcache_per_folder(const char *path, const char *folder, hcach
   {
     /* An existing file or a non-existing path not ending with a slash */
     snprintf(hcpath, sizeof(hcpath), "%s%s", path, suffix);
+    mutt_encode_path(hcpath, sizeof(hcpath), hcpath);
     return hcpath;
   }
 
@@ -609,6 +610,8 @@ static const char *hcache_per_folder(const char *path, const char *folder, hcach
     rc = snprintf(hcpath, sizeof(hcpath), "%s%s%s%s", path, slash ? "" : "/", name, suffix);
   }
 
+  mutt_encode_path(hcpath, sizeof(hcpath), hcpath);
+
   if (rc < 0) /* namer or fprintf failed.. should not happen */
     return path;
 
@@ -710,15 +713,12 @@ struct Header *mutt_hcache_restore(const unsigned char *d)
 static char *get_foldername(const char *folder)
 {
   char *p = NULL;
-  char path[_POSIX_PATH_MAX];
-
-  mutt_encode_path(path, sizeof(path), folder);
 
   /* if the folder is local, canonify the path to avoid
    * to ensure equivalent paths share the hcache */
   p = mutt_mem_malloc(PATH_MAX + 1);
-  if (!realpath(path, p))
-    mutt_str_replace(&p, path);
+  if (!realpath(folder, p))
+    mutt_str_replace(&p, folder);
 
   return p;
 }
index 515bbecab0dee75bf18d39055e4f36146fde6d7e..2a946c55e3cff225094a024200db9acacd19a83b 100644 (file)
--- a/muttlib.c
+++ b/muttlib.c
@@ -1394,9 +1394,18 @@ const char *mutt_make_version(void)
 void mutt_encode_path(char *dest, size_t dlen, const char *src)
 {
   char *p = mutt_str_strdup(src);
-  int rc = mutt_ch_convert_string(&p, Charset, "utf-8", 0);
+  int rc = mutt_ch_convert_string(&p, Charset, "us-ascii", 0);
   /* `src' may be NULL, such as when called from the pop3 driver. */
-  mutt_str_strfcpy(dest, (rc == 0) ? NONULL(p) : NONULL(src), dlen);
+  size_t len = mutt_str_strfcpy(dest, (rc == 0) ? NONULL(p) : NONULL(src), dlen);
+
+  /* convert the path to POSIX "Portable Filename Character Set" */
+  for (size_t i = 0; i < len; ++i)
+  {
+    if (!isalnum(dest[i]) && !strchr("/.-_", dest[i]))
+    {
+      dest[i] = '_';
+    }
+  }
   FREE(&p);
 }
 
index 57b0887aa9e6648aa898e14fd95e28ff372d406c..6b351510d618162d6fbd99e407d6adac4734ed6b 100644 (file)
--- a/newsrc.c
+++ b/newsrc.c
@@ -534,6 +534,7 @@ static void cache_expand(char *dst, size_t dstlen, struct Account *acct, char *s
   if (*c == '/')
     *c = '\0';
   mutt_expand_path(dst, dstlen);
+  mutt_encode_path(dst, dstlen, dst);
 }
 
 /**