From: Ken Brown <kbrown@cornell.edu>
To: Eli Zaretskii <eliz@gnu.org>, Paul Eggert <eggert@cs.ucla.edu>
Cc: "rms@gnu.org" <rms@gnu.org>, "schwab@suse.de" <schwab@suse.de>,
"36502@debbugs.gnu.org" <36502@debbugs.gnu.org>,
"npostavs@gmail.com" <npostavs@gmail.com>,
"monnier@iro.umontreal.ca" <monnier@iro.umontreal.ca>,
"dan@dpsutton.com" <dan@dpsutton.com>
Subject: bug#36502: Fwd: bug#36502: 27.0.50; infinite loop in file-name-case-insensitive-p
Date: Mon, 22 Jul 2019 02:16:47 +0000 [thread overview]
Message-ID: <22127ce6-182a-38ac-acc1-dfd09d727f18@cornell.edu> (raw)
In-Reply-To: <834l3fsc2c.fsf@gnu.org>
[-- Attachment #1: Type: text/plain, Size: 906 bytes --]
On 7/21/2019 10:21 AM, Eli Zaretskii wrote:
>> Cc: "rms@gnu.org" <rms@gnu.org>, "dan@dpsutton.com" <dan@dpsutton.com>,
>> "36502@debbugs.gnu.org" <36502@debbugs.gnu.org>,
>> "npostavs@gmail.com" <npostavs@gmail.com>,
>> "monnier@iro.umontreal.ca" <monnier@iro.umontreal.ca>,
>> "schwab@suse.de" <schwab@suse.de>
>> From: Paul Eggert <eggert@cs.ucla.edu>
>> Date: Sat, 20 Jul 2019 19:32:30 -0700
>>
>> My impression from looking at uses of file-name-absolute-p
>> is that changing it to return nil here would improve correctness of the callers,
>> though there would be a performance cost for this case of course.
>
> I agree.
>
> So Ken, please push your changes, and I would appreciate if you could
> also make the change in file-name-absolute-p (as a separate change),
> if you have time.
Patch attached. I didn't add a NEWS entry. Do you think this requires one?
Ken
[-- Attachment #2: 0001-Fix-file-name-absolute-p-for-names-starting-with.patch --]
[-- Type: text/plain, Size: 6435 bytes --]
From 3657bc708e96c6955f64e111daf52c3c3667a6db Mon Sep 17 00:00:00 2001
From: Ken Brown <kbrown@cornell.edu>
Date: Sun, 21 Jul 2019 22:04:07 -0400
Subject: [PATCH] Fix file-name-absolute-p for names starting with '~'
A file name starting with "~user" is now considered absolute only
if "user" is a valid login name. See the discussion starting at
Bug#36502#64.
* src/fileio.c (expand_tilde): New static function, extracted from
Fexpand_file_name.
(Fexpand_file_name, file_name_absolute_p)
(search_embedded_absfilename): Use it.
(Ffile_name_absolute_p): Update doc string.
* doc/lispref/files.texi (Relative File Names): Document the new
behavior of file-name-absolute-p.
---
doc/lispref/files.texi | 10 ++++-
src/fileio.c | 84 ++++++++++++++++++++++++++++--------------
2 files changed, 65 insertions(+), 29 deletions(-)
diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi
index 0519f787dc..18325b2049 100644
--- a/doc/lispref/files.texi
+++ b/doc/lispref/files.texi
@@ -2154,7 +2154,11 @@ Relative File Names
@defun file-name-absolute-p filename
This function returns @code{t} if file @var{filename} is an absolute
-file name or begins with @samp{~}, @code{nil} otherwise.
+file name or begins with @samp{~}, provided that an initial
+@samp{~@var{user}} corresponds to a valid login name @var{user}. The
+function returns @code{nil} otherwise. In the following examples,
+assume that there is a user named @samp{rms} but no user named
+@samp{quux}.
@example
@group
@@ -2162,6 +2166,10 @@ Relative File Names
@result{} t
@end group
@group
+(file-name-absolute-p "~quux/foo")
+ @result{} nil
+@end group
+@group
(file-name-absolute-p "rms/foo")
@result{} nil
@end group
diff --git a/src/fileio.c b/src/fileio.c
index 4c7625cad4..42455bb499 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -744,6 +744,35 @@ file_name_absolute_no_tilde_p (Lisp_Object name)
return IS_ABSOLUTE_FILE_NAME (SSDATA (name));
}
+/* NAME must start with "~user", where USER is not empty, followed by
+ nothing or a directory separator. LENGTH is the length of the
+ "~user" prefix. Return the absolute file name of USER's home
+ directory, or Qnil if there is no user named USER. */
+static Lisp_Object
+expand_tilde (const char *name, ptrdiff_t length)
+{
+ char *p;
+ const char *dir;
+ struct passwd *pw;
+ Lisp_Object result;
+ USE_SAFE_ALLOCA;
+
+ p = SAFE_ALLOCA (length);
+ memcpy (p, name + 1, length - 1);
+ p[length] = 0;
+
+ pw = getpwnam (p);
+ if (pw)
+ {
+ dir = pw->pw_dir;
+ result = make_unibyte_string (dir, strlen (dir));
+ }
+ else
+ result = Qnil;
+ SAFE_FREE ();
+ return result;
+}
+
DEFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0,
doc: /* Convert filename NAME to absolute, and canonicalize it.
Second arg DEFAULT-DIRECTORY is directory to start with if NAME is relative
@@ -788,7 +817,6 @@ DEFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0,
char *target;
ptrdiff_t tlen;
- struct passwd *pw;
#ifdef DOS_NT
int drive = 0;
bool collapse_newdir = true;
@@ -1153,25 +1181,20 @@ DEFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0,
}
else /* ~user/filename */
{
- char *o, *p;
+ char *p;
for (p = nm; *p && !IS_DIRECTORY_SEP (*p); p++)
continue;
- o = SAFE_ALLOCA (p - nm + 1);
- memcpy (o, nm, p - nm);
- o[p - nm] = 0;
block_input ();
- pw = getpwnam (o + 1);
+ Lisp_Object tem = expand_tilde (nm, p - nm);
unblock_input ();
- if (pw)
+ if (!NILP (tem))
{
- Lisp_Object tem;
-
- newdir = pw->pw_dir;
- /* `getpwnam' may return a unibyte string, which will
- bite us when we expect the directory to be multibyte. */
- tem = make_unibyte_string (newdir, strlen (newdir));
+ newdir = SSDATA (tem);
newdirlim = newdir + SBYTES (tem);
+ /* `getpwnam', which was used in `expand_tilde', may
+ return a unibyte string, which will bite us when we
+ expect the directory to be multibyte. */
if (multibyte && !STRING_MULTIBYTE (tem))
{
hdir = DECODE_FILE (tem);
@@ -1670,13 +1693,23 @@ DEAFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0,
bool
file_name_absolute_p (const char *filename)
{
- return
- (IS_DIRECTORY_SEP (*filename) || *filename == '~'
+ bool result
+ = (IS_DIRECTORY_SEP (*filename)
#ifdef DOS_NT
- || (IS_DRIVE (*filename) && IS_DEVICE_SEP (filename[1])
- && IS_DIRECTORY_SEP (filename[2]))
+ || (IS_DRIVE (*filename) && IS_DEVICE_SEP (filename[1])
+ && IS_DIRECTORY_SEP (filename[2]))
#endif
);
+ if (!result && *filename == '~')
+ {
+ const char *p;
+ for (p = filename + 1; *p && !IS_DIRECTORY_SEP (*p); p++);
+ if (p == filename + 1)
+ result = true;
+ else
+ result = !NILP (expand_tilde (filename, p - filename));
+ }
+ return result;
}
/* Put into BUF the concatenation of DIR and FILE, with an intervening
@@ -1794,20 +1827,13 @@ search_embedded_absfilename (char *nm, char *endp)
for (s = p; *s && !IS_DIRECTORY_SEP (*s); s++);
if (p[0] == '~' && s > p + 1) /* We've got "/~something/". */
{
- USE_SAFE_ALLOCA;
- char *o = SAFE_ALLOCA (s - p + 1);
- struct passwd *pw;
- memcpy (o, p, s - p);
- o [s - p] = 0;
-
/* If we have ~user and `user' exists, discard
everything up to ~. But if `user' does not exist, leave
~user alone, it might be a literal file name. */
block_input ();
- pw = getpwnam (o + 1);
+ Lisp_Object tem = expand_tilde (p, s - p);
unblock_input ();
- SAFE_FREE ();
- if (pw)
+ if (!NILP (tem))
return p;
}
else
@@ -2698,8 +2724,10 @@ DEFUN ("make-symbolic-link", Fmake_symbolic_link, Smake_symbolic_link, 2, 3,
\f
DEFUN ("file-name-absolute-p", Ffile_name_absolute_p, Sfile_name_absolute_p,
1, 1, 0,
- doc: /* Return t if FILENAME is an absolute file name or starts with `~'.
-On Unix, absolute file names start with `/'. */)
+ doc: /* Return t if FILENAME is an absolute file name.
+On Unix, absolute file names are usually required to start with `/';
+but here we also allow FILENAME to start with `~', provided that an
+initial ~USER corresponds to a valid login name USER. */)
(Lisp_Object filename)
{
CHECK_STRING (filename);
--
2.21.0
next prev parent reply other threads:[~2019-07-22 2:16 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-07-04 16:48 bug#36502: 27.0.50; infinite loop in file-name-case-insensitive-p Daniel Sutton
2019-07-04 18:08 ` Ken Brown
[not found] ` <CAMfzp7bhcmeY7QP4-ALfmBE4OojJthcYEVLR79zj-FrGx5s+WA@mail.gmail.com>
2019-07-05 1:32 ` Ken Brown
[not found] ` <CAMfzp7brsFLdpi04pDAL+O_yVuF7=EERzinVBKoQyTaLUtgwDA@mail.gmail.com>
[not found] ` <CAMfzp7Y=wA8_V=Tvm1iOtyXM-kqKZyx41Q4phJfnwmygHhJWLA@mail.gmail.com>
2019-07-05 3:05 ` bug#36502: Fwd: " Daniel Sutton
2019-07-06 12:49 ` Ken Brown
2019-07-06 13:27 ` Noam Postavsky
2019-07-06 15:38 ` Ken Brown
2019-07-06 16:14 ` Eli Zaretskii
2019-07-07 14:09 ` Ken Brown
2019-07-07 14:37 ` Eli Zaretskii
2019-07-07 19:30 ` Ken Brown
2019-07-08 12:25 ` Eli Zaretskii
2019-07-08 13:36 ` Ken Brown
2019-07-08 13:59 ` Eli Zaretskii
2019-07-08 15:17 ` Ken Brown
2019-07-08 16:44 ` Ken Brown
2019-07-08 17:23 ` Eli Zaretskii
2019-07-10 21:57 ` Ken Brown
2019-07-11 23:36 ` Richard Stallman
2019-07-12 6:41 ` Eli Zaretskii
2019-07-12 20:18 ` Ken Brown
2019-07-15 13:39 ` Ken Brown
2019-07-19 7:00 ` Eli Zaretskii
2019-07-20 9:19 ` Eli Zaretskii
2019-07-20 14:27 ` Ken Brown
2019-07-20 15:52 ` Eli Zaretskii
2019-07-21 2:32 ` Paul Eggert
2019-07-21 14:21 ` Eli Zaretskii
2019-07-21 14:30 ` Ken Brown
2019-07-22 2:16 ` Ken Brown [this message]
2019-07-24 21:36 ` Paul Eggert
2019-07-24 22:47 ` Ken Brown
2019-07-26 11:04 ` Andy Moreton
2019-07-08 14:37 ` Andreas Schwab
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=22127ce6-182a-38ac-acc1-dfd09d727f18@cornell.edu \
--to=kbrown@cornell.edu \
--cc=36502@debbugs.gnu.org \
--cc=dan@dpsutton.com \
--cc=eggert@cs.ucla.edu \
--cc=eliz@gnu.org \
--cc=monnier@iro.umontreal.ca \
--cc=npostavs@gmail.com \
--cc=rms@gnu.org \
--cc=schwab@suse.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).