mirror of
git://git.code.sf.net/p/zsh/code
synced 2024-09-28 15:01:21 +02:00
45291: A glob with a trailing slash will now match unreadable/unexecutable directories.
This commit is contained in:
parent
e899c21863
commit
edc04bd946
@ -1,3 +1,8 @@
|
||||
2020-01-15 dana <dana@dana.is>
|
||||
|
||||
* Daniel: 45291: Src/glob.c, Test/D02glob.ztst: A glob with a
|
||||
trailing slash will now match unreadable/unexecutable directories.
|
||||
|
||||
2020-01-15 Daniel Shahaf <danielsh@apache.org>
|
||||
|
||||
* 45288: Completion/Unix/Command/_git: Complete bisect/new as
|
||||
|
51
Src/glob.c
51
Src/glob.c
@ -279,11 +279,11 @@ addpath(char *s, int l)
|
||||
* foo/ can be used to reference a non-directory foo. Returns nonzero if *
|
||||
* the file does not exists. */
|
||||
|
||||
/**/
|
||||
static int
|
||||
statfullpath(const char *s, struct stat *st, int l)
|
||||
{
|
||||
char buf[PATH_MAX+1];
|
||||
int check_for_being_a_directory = 0;
|
||||
|
||||
DPUTS(strlen(s) + !*s + pathpos - pathbufcwd >= PATH_MAX,
|
||||
"BUG: statfullpath(): pathname too long");
|
||||
@ -294,16 +294,44 @@ statfullpath(const char *s, struct stat *st, int l)
|
||||
* Don't add the '.' if the path so far is empty, since
|
||||
* then we get bogus empty strings inserted as files.
|
||||
*/
|
||||
buf[pathpos - pathbufcwd] = '.';
|
||||
buf[pathpos - pathbufcwd + 1] = '\0';
|
||||
l = 0;
|
||||
if (st) {
|
||||
buf[pathpos - pathbufcwd] = '.';
|
||||
buf[pathpos - pathbufcwd + 1] = '\0';
|
||||
l = 0;
|
||||
}
|
||||
else {
|
||||
check_for_being_a_directory = 1;
|
||||
}
|
||||
}
|
||||
unmetafy(buf, NULL);
|
||||
if (!st) {
|
||||
char lbuf[1];
|
||||
return access(buf, F_OK) && (!l || readlink(buf, lbuf, 1) < 0);
|
||||
if (st) {
|
||||
return l ? lstat(buf, st) : stat(buf, st);
|
||||
}
|
||||
else if (check_for_being_a_directory) {
|
||||
struct stat tmp;
|
||||
if (stat(buf, &tmp))
|
||||
return -1;
|
||||
|
||||
return S_ISDIR(tmp.st_mode) ? 0 : -1;
|
||||
}
|
||||
else {
|
||||
char lbuf[1];
|
||||
|
||||
/* If it exists, signal success. */
|
||||
if (access(buf, F_OK) == 0)
|
||||
return 0;
|
||||
|
||||
/* Would a dangling symlink be good enough? */
|
||||
if (l == 0)
|
||||
return -1;
|
||||
|
||||
/* Is it a dangling symlink? */
|
||||
if (readlink(buf, lbuf, 1) >= 0)
|
||||
return 0;
|
||||
|
||||
/* Guess it doesn't exist, then. */
|
||||
return -1;
|
||||
}
|
||||
return l ? lstat(buf, st) : stat(buf, st);
|
||||
}
|
||||
|
||||
/* This may be set by qualifier functions to an array of strings to insert
|
||||
@ -327,11 +355,13 @@ insert(char *s, int checked)
|
||||
if (gf_listtypes || gf_markdirs) {
|
||||
/* Add the type marker to the end of the filename */
|
||||
mode_t mode;
|
||||
checked = statted = 1;
|
||||
if (statfullpath(s, &buf, 1)) {
|
||||
unqueue_signals();
|
||||
return;
|
||||
}
|
||||
else {
|
||||
checked = statted = 1;
|
||||
}
|
||||
mode = buf.st_mode;
|
||||
if (gf_follow) {
|
||||
if (!S_ISLNK(mode) || statfullpath(s, &buf2, 0))
|
||||
@ -387,11 +417,10 @@ insert(char *s, int checked)
|
||||
qn = qn->next;
|
||||
}
|
||||
} else if (!checked) {
|
||||
if (statfullpath(s, &buf, 1)) {
|
||||
if (statfullpath(s, NULL, 1)) {
|
||||
unqueue_signals();
|
||||
return;
|
||||
}
|
||||
statted = 1;
|
||||
news = dyncat(pathbuf, news);
|
||||
} else
|
||||
news = dyncat(pathbuf, news);
|
||||
|
@ -734,7 +734,7 @@
|
||||
mkdir -m 444 glob.tmp/secret-d444
|
||||
for 1 in 000 111 444 ; do ln -s secret-d$1 glob.tmp/secret-s$1; done
|
||||
print -rC 2 -- glob.tmp/secret-*/ glob.tmp/secret-*(-/)
|
||||
-f:unreadable directories can be globbed (users/24619, users/24626)
|
||||
0:unreadable directories can be globbed (users/24619, users/24626)
|
||||
>glob.tmp/secret-d000/ glob.tmp/secret-d000
|
||||
>glob.tmp/secret-d111/ glob.tmp/secret-d111
|
||||
>glob.tmp/secret-d444/ glob.tmp/secret-d444
|
||||
|
Loading…
Reference in New Issue
Block a user