Fix bug: (directory-file-name "///") returned "//"

* src/fileio.c (directory_file_name): For "///" and longer,
return "/", not "//", as per POSIX.
* test/src/fileio-tests.el (fileio-tests--directory-file-name)
(fileio-tests--file-name-as-directory): New tests.
This commit is contained in:
Paul Eggert 2017-09-07 17:46:12 -07:00
parent 53830c6336
commit aedc566a94
2 changed files with 27 additions and 7 deletions

View file

@ -566,15 +566,16 @@ is already present. */)
static ptrdiff_t
directory_file_name (char *dst, char *src, ptrdiff_t srclen, bool multibyte)
{
/* Process as Unix format: just remove any final slash.
But leave "/" and "//" unchanged. */
while (srclen > 1
/* In Unix-like systems, just remove any final slashes. However, if
they are all slashes, leave "/" and "//" alone, and treat "///"
and longer as if they were "/". */
if (! (srclen == 2 && IS_DIRECTORY_SEP (src[0])))
while (srclen > 1
#ifdef DOS_NT
&& !IS_ANY_SEP (src[srclen - 2])
&& !IS_ANY_SEP (src[srclen - 2])
#endif
&& IS_DIRECTORY_SEP (src[srclen - 1])
&& ! (srclen == 2 && IS_DIRECTORY_SEP (src[0])))
srclen--;
&& IS_DIRECTORY_SEP (src[srclen - 1]))
srclen--;
memcpy (dst, src, srclen);
dst[srclen] = 0;

View file

@ -44,3 +44,22 @@
"Check that any non-NULL ASCII character can appear in a symlink.
Also check that an encoding error can appear in a symlink."
(should (equal nil (fileio-tests--symlink-failure))))
(ert-deftest fileio-tests--directory-file-name ()
(should (equal (directory-file-name "/") "/"))
(should (equal (directory-file-name "//") "//"))
(should (equal (directory-file-name "///") "/"))
(should (equal (directory-file-name "////") "/"))
(should (equal (directory-file-name "/abc") "/abc"))
(should (equal (directory-file-name "/abc/") "/abc"))
(should (equal (directory-file-name "/abc//") "/abc")))
(ert-deftest fileio-tests--file-name-as-directory ()
(should (equal (file-name-as-directory "") "./"))
(should (equal (file-name-as-directory "/") "/"))
(should (equal (file-name-as-directory "//") "//"))
(should (equal (file-name-as-directory "///") "///"))
(should (equal (file-name-as-directory "////") "////"))
(should (equal (file-name-as-directory "/abc") "/abc/"))
(should (equal (file-name-as-directory "/abc/") "/abc/"))
(should (equal (file-name-as-directory "/abc//") "/abc//")))