From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Paul Eggert Newsgroups: gmane.emacs.bugs Subject: bug#26911: 25.2; eshell "cd .." doesn't work correctly with TRAMP Date: Wed, 26 Aug 2020 13:39:52 -0700 Organization: UCLA Computer Science Department Message-ID: References: Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------ED538890AE2E4A58FC74832C" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="32254"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.10.0 Cc: 26911@debbugs.gnu.org, Michael Albinus , 34384@debbugs.gnu.org To: Yegor Timoshenko Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Wed Aug 26 22:41:09 2020 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kB2EG-0008Gq-P6 for geb-bug-gnu-emacs@m.gmane-mx.org; Wed, 26 Aug 2020 22:41:08 +0200 Original-Received: from localhost ([::1]:43652 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kB2EF-0002op-Rr for geb-bug-gnu-emacs@m.gmane-mx.org; Wed, 26 Aug 2020 16:41:07 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:57208) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kB2EA-0002ob-01 for bug-gnu-emacs@gnu.org; Wed, 26 Aug 2020 16:41:02 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:57637) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kB2E9-0007KV-Md for bug-gnu-emacs@gnu.org; Wed, 26 Aug 2020 16:41:01 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1kB2E9-0007Q8-I2 for bug-gnu-emacs@gnu.org; Wed, 26 Aug 2020 16:41:01 -0400 X-Loop: help-debbugs@gnu.org In-Reply-To: Resent-From: Paul Eggert Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Wed, 26 Aug 2020 20:41:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 26911 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: confirmed Original-Received: via spool by 26911-submit@debbugs.gnu.org id=B26911.159847440428428 (code B ref 26911); Wed, 26 Aug 2020 20:41:01 +0000 Original-Received: (at 26911) by debbugs.gnu.org; 26 Aug 2020 20:40:04 +0000 Original-Received: from localhost ([127.0.0.1]:40943 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kB2DD-0007OP-A9 for submit@debbugs.gnu.org; Wed, 26 Aug 2020 16:40:04 -0400 Original-Received: from zimbra.cs.ucla.edu ([131.179.128.68]:43442) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kB2D9-0007Nn-LN; Wed, 26 Aug 2020 16:40:02 -0400 Original-Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 25FCE1600BA; Wed, 26 Aug 2020 13:39:54 -0700 (PDT) Original-Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id bXsRIHNhh9GI; Wed, 26 Aug 2020 13:39:52 -0700 (PDT) Original-Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id CE0991600C4; Wed, 26 Aug 2020 13:39:52 -0700 (PDT) X-Virus-Scanned: amavisd-new at zimbra.cs.ucla.edu Original-Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id 5Av8VwJoBTNd; Wed, 26 Aug 2020 13:39:52 -0700 (PDT) Original-Received: from [192.168.1.9] (cpe-75-82-69-226.socal.res.rr.com [75.82.69.226]) by zimbra.cs.ucla.edu (Postfix) with ESMTPSA id 8126D1600BA; Wed, 26 Aug 2020 13:39:52 -0700 (PDT) Autocrypt: addr=eggert@cs.ucla.edu; prefer-encrypt=mutual; keydata= LS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tCgptUUlOQkV5QWNtUUJFQURB QXlIMnhvVHU3cHBHNUQzYThGTVpFb243NGRDdmM0K3ExWEEySjJ0QnkycHdhVHFmCmhweHhk R0E5Smo1MFVKM1BENGJTVUVnTjh0TFowc2FuNDdsNVhUQUZMaTI0NTZjaVNsNW04c0thSGxH ZHQ5WG0KQUF0bVhxZVpWSVlYL1VGUzk2ZkR6ZjR4aEVtbS95N0xiWUVQUWRVZHh1NDd4QTVL aFRZcDVibHRGM1dZRHoxWQpnZDdneDA3QXV3cDdpdzdlTnZub0RUQWxLQWw4S1lEWnpiRE5D UUdFYnBZM2VmWkl2UGRlSStGV1FONFcra2doCnkrUDZhdTZQcklJaFlyYWV1YTdYRGRiMkxT MWVuM1NzbUUzUWpxZlJxSS9BMnVlOEpNd3N2WGUvV0szOEV6czYKeDc0aVRhcUkzQUZINmls QWhEcXBNbmQvbXNTRVNORnQ3NkRpTzFaS1FNcjlhbVZQa25qZlBtSklTcWRoZ0IxRApsRWR3 MzRzUk9mNlY4bVp3MHhmcVQ2UEtFNDZMY0ZlZnpzMGtiZzRHT1JmOHZqRzJTZjF0azVlVThN Qml5Ti9iClowM2JLTmpOWU1wT0REUVF3dVA4NGtZTGtYMndCeHhNQWhCeHdiRFZadWR6eERa SjFDMlZYdWpDT0pWeHEya2wKakJNOUVUWXVVR3FkNzVBVzJMWHJMdzYrTXVJc0hGQVlBZ1Jy NytLY3dEZ0JBZndoU Content-Language: en-US X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:186479 Archived-At: This is a multi-part message in MIME format. --------------ED538890AE2E4A58FC74832C Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit I ran into the expand-file-name bug outside of Tramp, and fixed it by installing the attached patch into Emacs master. I hope it fixes Bug#26911 too. With luck it (or something like it) might even bear on Bug#34834 too, so I'll cc this message there. (I don't use MS-Windows or Tramp so am not good at testing in those environments.) --------------ED538890AE2E4A58FC74832C Content-Type: text/x-patch; charset=UTF-8; name="0001-Fix-expand-file-name-symlink-to-dir-bug.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="0001-Fix-expand-file-name-symlink-to-dir-bug.patch" >From 14fb657ba82da346d36f05f88da26f1c5498b798 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 26 Aug 2020 13:25:35 -0700 Subject: [PATCH] Fix expand-file-name symlink-to-dir bug Problem reported by Yegor Timoshenko (Bug#26911), and I ran into it myself recently in normal-top-level. * doc/lispref/files.texi (File Name Expansion), etc/NEWS: Mention this. * src/fileio.c (Fexpand_file_name): Expand "/a/b/." to "/a/b/" not "/a/b", to avoid misinterpreting a symlink "/a/b". Similarly, expand "/a/b/c/.." to "/a/b/" not "/a/b". * test/lisp/net/tramp-tests.el (tramp-test05-expand-file-name): Adjust to match new behavior. (tramp-test05-expand-file-name-relative): This test now succeeds, at least on Fedora 31. * test/src/fileio-tests.el: (fileio-tests--expand-file-name-trailing-slash) New test. --- doc/lispref/files.texi | 16 ++++++++++++++-- etc/NEWS | 6 ++++++ src/fileio.c | 37 +++++++++++++++++++++--------------- test/lisp/net/tramp-tests.el | 11 ++++------- test/src/fileio-tests.el | 11 +++++++++++ 5 files changed, 57 insertions(+), 24 deletions(-) diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi index 92cbc2a1c9..090c54f8cd 100644 --- a/doc/lispref/files.texi +++ b/doc/lispref/files.texi @@ -2438,14 +2438,26 @@ File Name Expansion superroot above the root directory @file{/}. On other filesystems, @file{/../} is interpreted exactly the same as @file{/}. +If a filename must be that of a directory, its expansion must be too. +For example, if a filename ends in @samp{/} or @samp{/.} or @samp{/..} +then its expansion ends in @samp{/} so that it cannot be +misinterpreted as the name of a symbolic link: + +@example +@group +(expand-file-name "/a///b//.") + @result{} "/a/b/" +@end group +@end example + Expanding @file{.} or the empty string returns the default directory: @example @group (expand-file-name "." "/usr/spool/") - @result{} "/usr/spool" + @result{} "/usr/spool/" (expand-file-name "" "/usr/spool/") - @result{} "/usr/spool" + @result{} "/usr/spool/" @end group @end example diff --git a/etc/NEWS b/etc/NEWS index fae65a2227..14a75ca75d 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1157,6 +1157,12 @@ region's (or buffer's) end. This function can be used by modes to add elements to the 'choice' customization type of a variable. ++++ +** 'expand-file-name' no longer omits a trailing slash if the omission +changes the filename's meaning. E.g., (expand-file-name "/a/b/.") now +returns "/a/b/" not "/a/b", which might be misinterpreted as the name +of a symbolic link rather than of the directory it points to. + +++ ** New function 'file-modes-number-to-symbolic' to convert a numeric file mode specification into symbolic form. diff --git a/src/fileio.c b/src/fileio.c index 37072d9b6b..b70dff1c22 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -1065,7 +1065,7 @@ DEFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0, #endif /* WINDOWSNT */ #endif /* DOS_NT */ - /* If nm is absolute, look for `/./' or `/../' or `//''sequences; if + /* If nm is absolute, look for "/./" or "/../" or "//" sequences; if none are found, we can probably return right away. We will avoid allocating a new string if name is already fully expanded. */ if ( @@ -1398,7 +1398,7 @@ DEFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0, if (newdir) { - if (nm[0] == 0 || IS_DIRECTORY_SEP (nm[0])) + if (IS_DIRECTORY_SEP (nm[0])) { #ifdef DOS_NT /* If newdir is effectively "C:/", then the drive letter will have @@ -1433,14 +1433,16 @@ DEFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0, { *o++ = *p++; } - else if (p[1] == '.' - && (IS_DIRECTORY_SEP (p[2]) - || p[2] == 0)) + else if (p[1] == '.' && IS_DIRECTORY_SEP (p[2])) { - /* If "/." is the entire filename, keep the "/". Otherwise, - just delete the whole "/.". */ - if (o == target && p[2] == '\0') - *o++ = *p; + /* Replace "/./" with "/". */ + p += 2; + } + else if (p[1] == '.' && !p[2]) + { + /* At the end of the file name, replace "/." with "/". + The trailing "/" is for symlinks. */ + *o++ = *p; p += 2; } else if (p[1] == '.' && p[2] == '.' @@ -1459,18 +1461,23 @@ DEFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0, #ifdef WINDOWSNT char *prev_o = o; #endif - while (o != target && (--o, !IS_DIRECTORY_SEP (*o))) - continue; + while (o != target) + { + o--; + if (IS_DIRECTORY_SEP (*o)) + { + /* Keep "/" at the end of the name, for symlinks. */ + o += p[3] == 0; + + break; + } + } #ifdef WINDOWSNT /* Don't go below server level in UNC filenames. */ if (o == target + 1 && IS_DIRECTORY_SEP (*o) && IS_DIRECTORY_SEP (*target)) o = prev_o; - else #endif - /* Keep initial / only if this is the whole name. */ - if (o == target && IS_ANY_SEP (*o) && p[3] == 0) - ++o; p += 3; } else if (IS_DIRECTORY_SEP (p[1]) diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index 7e9ae33f84..aa00c07f79 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -2131,16 +2131,16 @@ tramp-test05-expand-file-name (expand-file-name "/method:host:/path/../file") "/method:host:/file")) (should (string-equal - (expand-file-name "/method:host:/path/.") "/method:host:/path")) + (expand-file-name "/method:host:/path/.") "/method:host:/path/")) (should (string-equal (expand-file-name "/method:host:/path/..") "/method:host:/")) (should (string-equal - (expand-file-name "." "/method:host:/path/") "/method:host:/path")) + (expand-file-name "." "/method:host:/path/") "/method:host:/path/")) (should (string-equal - (expand-file-name "" "/method:host:/path/") "/method:host:/path")) + (expand-file-name "" "/method:host:/path/") "/method:host:/path/")) ;; Quoting local part. (should (string-equal @@ -2155,12 +2155,9 @@ tramp-test05-expand-file-name "/method:host:/:/~/path/file")))) ;; The following test is inspired by Bug#26911 and Bug#34834. They -;; are rather bugs in `expand-file-name', and it fails for all Emacs -;; versions. Test added for later, when they are fixed. +;; were bugs in `expand-file-name'. (ert-deftest tramp-test05-expand-file-name-relative () "Check `expand-file-name'." - ;; Mark as failed until bug has been fixed. - :expected-result :failed (skip-unless (tramp--test-enabled)) ;; These are the methods the test doesn't fail. diff --git a/test/src/fileio-tests.el b/test/src/fileio-tests.el index 96b03a0137..1516590795 100644 --- a/test/src/fileio-tests.el +++ b/test/src/fileio-tests.el @@ -108,6 +108,17 @@ fileio-tests--relative-HOME (should (equal (expand-file-name "~/bar") "x:/foo/bar"))) (setenv "HOME" old-home))) +(ert-deftest fileio-tests--expand-file-name-trailing-slash () + (dolist (fooslashalias '("foo/" "foo//" "foo/." "foo//." "foo///././." + "foo/a/..")) + (should (equal (expand-file-name fooslashalias "/") "/foo/")) + (should (equal (expand-file-name (concat "/" fooslashalias)) "/foo/"))) + (should (equal (expand-file-name "." "/usr/spool/") "/usr/spool/")) + (should (equal (expand-file-name "" "/usr/spool/") "/usr/spool/")) + ;; Trailing "B/C/.." means B must be a directory. + (should (equal (expand-file-name "/a/b/c/..") "/a/b/")) + (should (equal (expand-file-name "/a/b/c/../") "/a/b/"))) + (ert-deftest fileio-tests--insert-file-interrupt () (let ((text "-*- coding: binary -*-\n\xc3\xc3help") f) -- 2.17.1 --------------ED538890AE2E4A58FC74832C--