1
0
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:
Daniel Shahaf 2020-01-13 00:27:24 +00:00 committed by dana
parent e899c21863
commit edc04bd946
3 changed files with 46 additions and 12 deletions

@ -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

@ -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