This fixes the edge cases tested by Derek Martin.
  "foo/bar/" + "/baz"  gave: "foo/bar//baz" should be: "foo/bar/baz"
  ""         + "/baz"  gave: "//baz"        should be "/bar"
  "/"        + "/foo"  gave  "//foo"        should be "/foo"

All three bugs were triggered by a leading "/" in fname.

The one line strspn() fix is by Alejandro Colomar, but has also been
applied to the lib.c version.

Many thanks to Derek Martin, for noticing the edge case failures,
creating a suite of tests, and also working on proposed patches to fix
the problem.  Also thanks to Rene Kita for his feedback and proposed
version.

In the end, this was the simplest version that was easy to apply to
both concat_path() functions.
---
 lib.c     | 2 ++
 muttlib.c | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/lib.c b/lib.c
index 44f0e869..649fdb3a 100644
--- a/lib.c
+++ b/lib.c
@@ -763,6 +763,8 @@ char *mutt_concat_path(char *d, const char *dir, const char 
*fname, size_t l)
   if (!*fname || (*dir && dir[strlen(dir)-1] == '/'))
     fmt = "%s%s";
 
+  fname += strspn(fname, "/");
+
   snprintf(d, l, fmt, dir, fname);
   return d;
 }
diff --git a/muttlib.c b/muttlib.c
index 59a48378..a9fe8779 100644
--- a/muttlib.c
+++ b/muttlib.c
@@ -1394,6 +1394,8 @@ void mutt_buffer_concat_path(BUFFER *d, const char *dir, 
const char *fname)
   if (!*fname || (*dir && dir[strlen(dir)-1] == '/'))
     fmt = "%s%s";
 
+  fname += strspn(fname, "/");
+
   mutt_buffer_printf(d, fmt, dir, fname);
 }
 
-- 
2.54.0

Reply via email to