From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/11109 Path: news.gmane.org!.POSTED!not-for-mail From: Joakim Sindholt Newsgroups: gmane.linux.lib.musl.general Subject: fix nftw when called with paths ending in slash(es) Date: Tue, 07 Mar 2017 10:47:38 +0100 Message-ID: <1488880058.29564.0@mail.zhasha.com> Reply-To: musl@lists.openwall.com NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-ni7zyJmHi1wNi4ItkeLR" X-Trace: blaine.gmane.org 1488880078 19886 195.159.176.226 (7 Mar 2017 09:47:58 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Tue, 7 Mar 2017 09:47:58 +0000 (UTC) To: musl@lists.openwall.com Original-X-From: musl-return-11124-gllmg-musl=m.gmane.org@lists.openwall.com Tue Mar 07 10:47:52 2017 Return-path: Envelope-to: gllmg-musl@m.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by blaine.gmane.org with smtp (Exim 4.84_2) (envelope-from ) id 1clBif-0004Ms-K9 for gllmg-musl@m.gmane.org; Tue, 07 Mar 2017 10:47:49 +0100 Original-Received: (qmail 20382 invoked by uid 550); 7 Mar 2017 09:47:52 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Original-Received: (qmail 20352 invoked from network); 7 Mar 2017 09:47:50 -0000 X-Mailer: geary/0.11.2 Xref: news.gmane.org gmane.linux.lib.musl.general:11109 Archived-At: --=-ni7zyJmHi1wNi4ItkeLR Content-Type: text/plain; charset=utf-8; format=flowed I sent a version of this patch to the list previously but I believe the opinion was that nftw should preserve slashes as best it could, so here's one that does that. Using the test program from man nftw: $ ./a.out ftw d 0 4096 ftw 0 ftw d 1 4096 ftw/a 4 a f 2 0 ftw/a/f 6 f d 2 4096 ftw/a/d 6 d d 3 4096 ftw/a/d/e 8 e d 1 4096 ftw/b 4 b f 2 0 ftw/b/g 6 g f 1 0 ftw/c 4 c $ ./a.out ftw/ d 0 4096 ftw 0 ftw d 1 4096 ftw/a 4 a f 2 0 ftw/a/f 6 f d 2 4096 ftw/a/d 6 d d 3 4096 ftw/a/d/e 8 e d 1 4096 ftw/b 4 b f 2 0 ftw/b/g 6 g f 1 0 ftw/c 4 c $ ./a.out ftw// d 0 4096 ftw 0 ftw d 1 4096 ftw//a 5 a f 2 0 ftw//a/f 7 f d 2 4096 ftw//a/d 7 d d 3 4096 ftw//a/d/e 9 e d 1 4096 ftw//b 5 b f 2 0 ftw//b/g 7 g f 1 0 ftw//c 5 c And on the root $ ./a.out / | sed 4q d 0 4096 / 0 / d 1 4096 /projects 1 projects d 2 4096 /projects/p9.git 10 p9.git d 3 4096 /projects/p9.git/hooks 17 hooks $ ./a.out // | sed 4q d 0 4096 // 1 / d 1 4096 //projects 2 projects d 2 4096 //projects/p9.git 11 p9.git d 3 4096 //projects/p9.git/hooks 18 hooks However glibc does this: $ ./a.out / | sed 4q d 0 4096 / 1 d 1 4096 /projects 1 projects d 2 4096 /projects/p9.git 10 p9.git d 3 4096 /projects/p9.git/hooks 17 hooks The standard just says: > The value of base is the offset of the object's filename in the > pathname passed as the first argument to fn Which I believe should be interpreted as the root dir being called / but I'm not sure. It's a simple change either way. --=-ni7zyJmHi1wNi4ItkeLR Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-fix-nftw-when-called-with-paths-ending-in-slash-es.patch >From 579501476c880bff651ec3ea5d3116ae26c9941e Mon Sep 17 00:00:00 2001 From: Joakim Sindholt Date: Tue, 7 Mar 2017 10:31:37 +0100 Subject: [PATCH] fix nftw when called with paths ending in slash(es) --- src/misc/nftw.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/misc/nftw.c b/src/misc/nftw.c index efb2b89..d82b909 100644 --- a/src/misc/nftw.c +++ b/src/misc/nftw.c @@ -22,13 +22,13 @@ struct history static int do_nftw(char *path, int (*fn)(const char *, const struct stat *, int, struct FTW *), int fd_limit, int flags, struct history *h) { - size_t l = strlen(path), j = l && path[l-1]=='/' ? l-1 : l; + size_t l = strlen(path), j = l && path[l-1]=='/' ? l-1 : l, k; struct stat st; struct history new; int type; int r; struct FTW lev; - char *name; + char *end = 0; if ((flags & FTW_PHYS) ? lstat(path, &st) : stat(path, &st) < 0) { if (!(flags & FTW_PHYS) && errno==ENOENT && !lstat(path, &st)) @@ -53,13 +53,29 @@ static int do_nftw(char *path, int (*fn)(const char *, const struct stat *, int, new.dev = st.st_dev; new.ino = st.st_ino; new.level = h ? h->level+1 : 0; - new.base = l+1; + new.base = j+1; lev.level = new.level; - lev.base = h ? h->base : (name=strrchr(path, '/')) ? name-path : 0; + if (h) { + lev.base = h->base; + } else { + lev.base = k = j; + while (k > 0 && path[k] == '/') + --k; + if (k > 0) { + end = path+k+1; + while (k > 0 && path[k-1] != '/') + --k; + lev.base = k; + } + } + if (end) + *end = '\0'; if (!(flags & FTW_DEPTH) && (r=fn(path, &st, type, &lev))) return r; + if (end) + *end = '/'; for (; h; h = h->chain) if (h->dev == st.st_dev && h->ino == st.st_ino) -- 2.10.2 --=-ni7zyJmHi1wNi4ItkeLR--