aboutsummaryrefslogtreecommitdiff
path: root/toys/posix/find.c
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2015-09-12 15:46:46 -0500
committerRob Landley <rob@landley.net>2015-09-12 15:46:46 -0500
commitedae0b07db841e3bf8449d591971f04c9957ecbc (patch)
tree186c7e6504e3217ba630714b4577c23f4ac3ec94 /toys/posix/find.c
parente5354ca12a232b3f97726214254a868771cb70d1 (diff)
downloadtoybox-edae0b07db841e3bf8449d591971f04c9957ecbc.tar.gz
Fix a find segfault.
Elliott Hughes found a bug https://android-review.googlesource.com/#/c/170020/ and Daniel K. Levy worked out the problem: the user/group/newer arguments to find weren't consuming their arguments when not checking the results of their comparison (because an earlier test had already caused their parenthetical group to fail). This confused the argument parsing logic and could lead to segfaults. I applied a different fix that reorganized the existing tests instead of adding a new test. (Looks like a big commit but it's mostly whitespace due to extra curly brackets changing indendentation levels.)
Diffstat (limited to 'toys/posix/find.c')
-rw-r--r--toys/posix/find.c36
1 files changed, 20 insertions, 16 deletions
diff --git a/toys/posix/find.c b/toys/posix/find.c
index 10585294..aca19845 100644
--- a/toys/posix/find.c
+++ b/toys/posix/find.c
@@ -336,26 +336,30 @@ static int do_find(struct dirtree *new)
} u;
} *udl;
- if (!new && ss[1]) {
- udl = xmalloc(sizeof(*udl));
- dlist_add_nomalloc(&TT.argdata, (void *)udl);
+ if (!new) {
+ if (ss[1]) {
+ udl = xmalloc(sizeof(*udl));
+ dlist_add_nomalloc(&TT.argdata, (void *)udl);
- if (*s == 'u') udl->u.uid = xgetpwnamid(ss[1])->pw_uid;
- else if (*s == 'g') udl->u.gid = xgetgrnamid(ss[1])->gr_gid;
- else {
- struct stat st;
+ if (*s == 'u') udl->u.uid = xgetpwnamid(ss[1])->pw_uid;
+ else if (*s == 'g') udl->u.gid = xgetgrnamid(ss[1])->gr_gid;
+ else {
+ struct stat st;
- xstat(ss[1], &st);
- udl->u.tm = st.st_mtim;
+ xstat(ss[1], &st);
+ udl->u.tm = st.st_mtim;
+ }
}
- } else if (check) {
+ } else {
udl = (void *)llist_pop(&argdata);
- if (*s == 'u') test = new->st.st_uid == udl->u.uid;
- else if (*s == 'g') test = new->st.st_gid == udl->u.gid;
- else {
- test = new->st.st_mtim.tv_sec > udl->u.tm.tv_sec;
- if (new->st.st_mtim.tv_sec == udl->u.tm.tv_sec)
- test = new->st.st_mtim.tv_nsec > udl->u.tm.tv_nsec;
+ if (check) {
+ if (*s == 'u') test = new->st.st_uid == udl->u.uid;
+ else if (*s == 'g') test = new->st.st_gid == udl->u.gid;
+ else {
+ test = new->st.st_mtim.tv_sec > udl->u.tm.tv_sec;
+ if (new->st.st_mtim.tv_sec == udl->u.tm.tv_sec)
+ test = new->st.st_mtim.tv_nsec > udl->u.tm.tv_nsec;
+ }
}
}
} else if (!strcmp(s, "exec") || !strcmp("ok", s)