unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#28156: Emacs quietly munges symlink contents
@ 2017-08-20 10:28 Paul Eggert
  2017-08-20 13:48 ` Michael Albinus
  2017-08-20 14:37 ` Eli Zaretskii
  0 siblings, 2 replies; 30+ messages in thread
From: Paul Eggert @ 2017-08-20 10:28 UTC (permalink / raw)
  To: 28156; +Cc: Michael Albinus

[-- Attachment #1: Type: text/plain, Size: 961 bytes --]

Tags: patch

The attached patch fixes some Emacs behavior that disagrees with the 
documentation.  Although the user manual says that make-symbolic-link "does
not expand the argument TARGET", Emacs expands leading "~" in the target. Also, 
file-symlink-p quietly munges symlink contents if they appear to be a Tramp file 
name. This behavior makes it impossible to write Emacs code that deals with 
arbitrary local symbolic links, and Emacs mishandles copying of some symlinks 
for this reason. At the operating system level, symlink targets are merely 
strings, and are not file names that are interpreted (any interpretation occurs 
later, only when the symlinks are followed), and Emacs should be consistent with 
that.

It strikes me that a similar change probably needs to be made to Tramp, so that 
remote symlinks also can be arbitrary strings too. However, that's outside my 
expertise so this patch affects only local symlink contents.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Do-not-munge-contents-of-local-symbolic-links.patch --]
[-- Type: text/x-patch; name="0001-Do-not-munge-contents-of-local-symbolic-links.patch", Size: 6077 bytes --]

From faf68f4979509cd61b5f666479b66ec5b37594d6 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Sun, 20 Aug 2017 03:13:52 -0700
Subject: [PATCH] Do not munge contents of local symbolic links

This lets Emacs deal with arbitrary local symlinks without
mishandling their contents.  For example,
(progn (shell-command "ln -fs '~' 'x'") (rename-file "x" "/tmp/x"))
now consistently creates a symbolic link from '/tmp/x' to '~'.
Formerly, it did that only if the working directory was on the
same filesystem as /tmp; otherwise, it expanded the '~' to
the user's home directory.
* etc/NEWS: Document the change.
* src/fileio.c (Fmake_symbolic_link): Do not expand leading
"~" in the target, and look for special constructs only in
the new link name, not the target.
(emacs_readlinkat): Do not preprend "/:" to the link target if
it starts with "/" and contains ":" before NUL.
* test/lisp/net/tramp-tests.el (tramp-test21-file-links):
Adjust to new behavior.
* test/src/fileio-tests.el (try-link): Rename from try-char,
and accept a string instead of a char.  All uses changed.
(fileio-tests--symlink-failure): Also test leading ~, and "/:",
to test the new behavior.
---
 etc/NEWS                     |  8 ++++++++
 src/fileio.c                 | 18 ------------------
 test/lisp/net/tramp-tests.el |  9 ++++++---
 test/src/fileio-tests.el     | 21 ++++++++++-----------
 4 files changed, 24 insertions(+), 32 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index 7774d75..104ee04 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1204,6 +1204,14 @@ instead of to utf-8.  Before this change, Emacs would sometimes
 mishandle file names containing these control characters.
 
 +++
+** 'file-attributes', 'file-symlink-p' and 'make-symbolic-link' no
+longer quietly mutate the target of a local symbolic link.  In
+particular, 'file-attributes' and 'file-symlink-p' no longer prepend
+"/:" to some targets of local symbolic links, and 'make-symbolic-link'
+no longer expands '~' at the start of a link target.  This change lets
+Emacs access and copy arbitrary local symbolic links.
+
++++
 ** Module functions are now implemented slightly differently; in
 particular, the function 'internal--module-call' has been removed.
 Code that depends on undocumented internals of the module system might
diff --git a/src/fileio.c b/src/fileio.c
index f954ac1..ce243c3 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -2423,21 +2423,8 @@ This happens for interactive use with M-x.  */)
   Lisp_Object encoded_target, encoded_linkname;
 
   CHECK_STRING (target);
-  /* If the link target has a ~, we must expand it to get
-     a truly valid file name.  Otherwise, do not expand;
-     we want to permit links to relative file names.  */
-  if (SREF (target, 0) == '~')
-    target = Fexpand_file_name (target, Qnil);
-
   linkname = expand_cp_target (target, linkname);
 
-  /* If the file name has special constructs in it,
-     call the corresponding file handler.  */
-  handler = Ffind_file_name_handler (target, Qmake_symbolic_link);
-  if (!NILP (handler))
-    return call4 (handler, Qmake_symbolic_link, target,
-		  linkname, ok_if_already_exists);
-
   /* If the new link name has special constructs in it,
      call the corresponding file handler.  */
   handler = Ffind_file_name_handler (linkname, Qmake_symbolic_link);
@@ -2635,11 +2622,6 @@ emacs_readlinkat (int fd, char const *filename)
     return Qnil;
 
   val = build_unibyte_string (buf);
-  if (buf[0] == '/' && strchr (buf, ':'))
-    {
-      AUTO_STRING (slash_colon, "/:");
-      val = concat2 (slash_colon, val);
-    }
   if (buf != readlink_buf)
     xfree (buf);
   val = DECODE_FILE (val);
diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el
index 9dc276b..0740996 100644
--- a/test/lisp/net/tramp-tests.el
+++ b/test/lisp/net/tramp-tests.el
@@ -2538,13 +2538,16 @@ tramp--test-backtrace
 	    (should-error (make-symbolic-link tmp-name1 tmp-name2))
 	    (make-symbolic-link tmp-name1 tmp-name2 'ok-if-already-exists)
 	    (should (file-symlink-p tmp-name2))
-	    ;; `tmp-name3' is a local file name.
-	    (should-error (make-symbolic-link tmp-name1 tmp-name3)))
+	    ;; `tmp-name3' is a local file name, so its target is not
+	    ;; interpreted.
+	    (make-symbolic-link tmp-name1 tmp-name3)
+	    (should (equal tmp-name1 (file-symlink-p tmp-name3))))
 
 	;; Cleanup.
 	(ignore-errors
 	  (delete-file tmp-name1)
-	  (delete-file tmp-name2)))
+	  (delete-file tmp-name2)
+	  (delete-file tmp-name3)))
 
       ;; Check `add-name-to-file'.
       (unwind-protect
diff --git a/test/src/fileio-tests.el b/test/src/fileio-tests.el
index 2ef1b55..5103d2f 100644
--- a/test/src/fileio-tests.el
+++ b/test/src/fileio-tests.el
@@ -19,14 +19,13 @@
 
 (require 'ert)
 
-(defun try-char (char link)
-  (let ((target (string char)))
-    (make-symbolic-link target link)
-    (let* ((read-link (file-symlink-p link))
-           (failure (unless (string-equal target read-link)
-                      (list 'string-equal target read-link))))
-      (delete-file link)
-      failure)))
+(defun try-link (target link)
+  (make-symbolic-link target link)
+  (let* ((read-link (file-symlink-p link))
+         (failure (unless (string-equal target read-link)
+                    (list 'string-equal target read-link))))
+    (delete-file link)
+    failure))
 
 (defun fileio-tests--symlink-failure ()
   (let* ((dir (make-temp-file "fileio" t))
@@ -36,9 +35,9 @@ fileio-tests--symlink-failure
               (char 0))
           (while (and (not failure) (< char 127))
             (setq char (1+ char))
-            (unless (= char ?~)
-              (setq failure (try-char char link))))
-          failure)
+            (setq failure (try-link (string char) link)))
+          (or failure
+              (try-link "/:" link)))
       (delete-directory dir t))))
 
 (ert-deftest fileio-tests--odd-symlink-chars ()
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2017-08-27  1:53 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-08-20 10:28 bug#28156: Emacs quietly munges symlink contents Paul Eggert
2017-08-20 13:48 ` Michael Albinus
2017-08-20 14:37 ` Eli Zaretskii
2017-08-20 15:09   ` Philipp Stephani
2017-08-20 15:38     ` Eli Zaretskii
2017-08-20 17:54       ` Paul Eggert
2017-08-20 18:28         ` Michael Albinus
2017-08-20 18:53           ` Paul Eggert
2017-08-20 19:15             ` Michael Albinus
2017-08-20 21:47               ` Paul Eggert
2017-08-21  7:36                 ` Michael Albinus
2017-08-20 19:21             ` Eli Zaretskii
2017-08-20 21:31               ` Paul Eggert
2017-08-21  2:34                 ` Eli Zaretskii
2017-08-21  8:34                   ` Paul Eggert
2017-08-21 14:25                     ` Eli Zaretskii
2017-08-21 15:58                       ` Paul Eggert
2017-08-20 19:16         ` Eli Zaretskii
2017-08-21 17:34           ` Paul Eggert
2017-08-21 17:59             ` Eli Zaretskii
2017-08-21 20:30               ` Paul Eggert
2017-08-22  7:28                 ` Michael Albinus
2017-08-22 16:03                   ` Paul Eggert
2017-08-24 11:38                     ` Michael Albinus
2017-08-25  5:12                       ` Paul Eggert
2017-08-25 12:45                         ` Michael Albinus
2017-08-26 13:16                           ` Michael Albinus
2017-08-27  1:53                           ` Paul Eggert
2017-08-20 22:19       ` npostavs
2017-08-20 23:00         ` Paul Eggert

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).