summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2018-11-14 20:36:09 -0500
committerTavian Barnes <tavianator@tavianator.com>2018-11-14 20:42:10 -0500
commit90c7fba2d3d1081fb7a4d6a3d9a7e3c2132f33f6 (patch)
tree234a467f2a8936472107c770d45099da105ff73e
parent14065fe78c133bc49e46557a8cfdec7ed6b618bc (diff)
downloadbfs-90c7fba2d3d1081fb7a4d6a3d9a7e3c2132f33f6.tar.xz
exec: Reject -exec \; without a command
Prior to this, we'd fork and then segfault on every file as NULL was passed to execvpe(). Found while looking through old FreeBSD find bugs: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=36521 bfs still supports the (dubious, possibly unintentional?) GNU find extension to POSIX that allows $ bfs -exec {} \;
-rw-r--r--exec.c5
-rwxr-xr-xtests.sh16
2 files changed, 20 insertions, 1 deletions
diff --git a/exec.c b/exec.c
index c2163e3..35bf061 100644
--- a/exec.c
+++ b/exec.c
@@ -160,6 +160,11 @@ struct bfs_exec *parse_bfs_exec(char **argv, enum bfs_exec_flags flags, const st
execbuf->tmpl_argv = argv + 1;
execbuf->tmpl_argc = i - 1;
+ if (execbuf->tmpl_argc == 0) {
+ cfprintf(cerr, "%{er}error: %s: Missing command.%{rs}\n", argv[0]);
+ goto fail;
+ }
+
execbuf->argv_cap = execbuf->tmpl_argc + 1;
execbuf->argv = malloc(execbuf->argv_cap*sizeof(*execbuf->argv));
if (!execbuf->argv) {
diff --git a/tests.sh b/tests.sh
index 4ced3c0..35f0224 100755
--- a/tests.sh
+++ b/tests.sh
@@ -439,6 +439,8 @@ gnu_tests=(
test_empty
+
+ test_exec_nothing
test_exec_substring
test_execdir
@@ -498,6 +500,8 @@ gnu_tests=(
test_nouser
+ test_ok_nothing
+
test_okdir_plus_semicolon
test_perm_000_slash
@@ -1122,7 +1126,12 @@ function test_size_big() {
}
function test_exec() {
- bfs_diff basic -exec echo '{}' ';'
+ bfs_diff basic -exec echo '{}' \;
+}
+
+function test_exec_nothing() {
+ # Regression test: don't segfault on missing command
+ ! invoke_bfs basic -exec \; 2>/dev/null
}
function test_exec_plus() {
@@ -1362,6 +1371,11 @@ function test_not_prune() {
bfs_diff basic \! \( -name foo -prune \)
}
+function test_ok_nothing() {
+ # Regression test: don't segfault on missing command
+ ! invoke_bfs basic -ok \; 2>/dev/null
+}
+
function test_ok_stdin() {
# -ok should *not* close stdin
# See https://savannah.gnu.org/bugs/?24561