1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-08-13 03:30:54 +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

View file

@ -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> 2020-01-15 Daniel Shahaf <danielsh@apache.org>
* 45288: Completion/Unix/Command/_git: Complete bisect/new as * 45288: Completion/Unix/Command/_git: Complete bisect/new as

View file

@ -279,11 +279,11 @@ addpath(char *s, int l)
* foo/ can be used to reference a non-directory foo. Returns nonzero if * * foo/ can be used to reference a non-directory foo. Returns nonzero if *
* the file does not exists. */ * the file does not exists. */
/**/
static int static int
statfullpath(const char *s, struct stat *st, int l) statfullpath(const char *s, struct stat *st, int l)
{ {
char buf[PATH_MAX+1]; char buf[PATH_MAX+1];
int check_for_being_a_directory = 0;
DPUTS(strlen(s) + !*s + pathpos - pathbufcwd >= PATH_MAX, DPUTS(strlen(s) + !*s + pathpos - pathbufcwd >= PATH_MAX,
"BUG: statfullpath(): pathname too long"); "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 * Don't add the '.' if the path so far is empty, since
* then we get bogus empty strings inserted as files. * then we get bogus empty strings inserted as files.
*/ */
buf[pathpos - pathbufcwd] = '.'; if (st) {
buf[pathpos - pathbufcwd + 1] = '\0'; buf[pathpos - pathbufcwd] = '.';
l = 0; buf[pathpos - pathbufcwd + 1] = '\0';
l = 0;
}
else {
check_for_being_a_directory = 1;
}
} }
unmetafy(buf, NULL); unmetafy(buf, NULL);
if (!st) { if (st) {
char lbuf[1]; return l ? lstat(buf, st) : stat(buf, st);
return access(buf, F_OK) && (!l || readlink(buf, lbuf, 1) < 0); }
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 /* 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) { if (gf_listtypes || gf_markdirs) {
/* Add the type marker to the end of the filename */ /* Add the type marker to the end of the filename */
mode_t mode; mode_t mode;
checked = statted = 1;
if (statfullpath(s, &buf, 1)) { if (statfullpath(s, &buf, 1)) {
unqueue_signals(); unqueue_signals();
return; return;
} }
else {
checked = statted = 1;
}
mode = buf.st_mode; mode = buf.st_mode;
if (gf_follow) { if (gf_follow) {
if (!S_ISLNK(mode) || statfullpath(s, &buf2, 0)) if (!S_ISLNK(mode) || statfullpath(s, &buf2, 0))
@ -387,11 +417,10 @@ insert(char *s, int checked)
qn = qn->next; qn = qn->next;
} }
} else if (!checked) { } else if (!checked) {
if (statfullpath(s, &buf, 1)) { if (statfullpath(s, NULL, 1)) {
unqueue_signals(); unqueue_signals();
return; return;
} }
statted = 1;
news = dyncat(pathbuf, news); news = dyncat(pathbuf, news);
} else } else
news = dyncat(pathbuf, news); news = dyncat(pathbuf, news);

View file

@ -734,7 +734,7 @@
mkdir -m 444 glob.tmp/secret-d444 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 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-*(-/) 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-d000/ glob.tmp/secret-d000
>glob.tmp/secret-d111/ glob.tmp/secret-d111 >glob.tmp/secret-d111/ glob.tmp/secret-d111
>glob.tmp/secret-d444/ glob.tmp/secret-d444 >glob.tmp/secret-d444/ glob.tmp/secret-d444