summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bfs.h2
-rw-r--r--eval.c7
-rw-r--r--parse.c10
-rwxr-xr-xtests.sh7
-rw-r--r--tests/test_X.out17
-rw-r--r--tests/test_follow_comma.out4
-rw-r--r--tests/test_nohidden.out4
7 files changed, 51 insertions, 0 deletions
diff --git a/bfs.h b/bfs.h
index 53c8b1e..191cb9e 100644
--- a/bfs.h
+++ b/bfs.h
@@ -102,6 +102,8 @@ struct cmdline {
int optlevel;
/** Debugging flags. */
enum debug_flags debug;
+ /** Whether to only handle paths with xargs-safe characters. */
+ bool xargs_safe;
/** Whether to ignore deletions that race with bfs. */
bool ignore_races;
diff --git a/eval.c b/eval.c
index 929eeba..8c33d21 100644
--- a/eval.c
+++ b/eval.c
@@ -964,6 +964,13 @@ static enum bftw_action cmdline_callback(struct BFTW *ftwbuf, void *ptr) {
goto done;
}
+ if (cmdline->xargs_safe && strpbrk(ftwbuf->path, " \t\n\'\"\\")) {
+ args->ret = -1;
+ cfprintf(cmdline->cerr, "%{er}'%s': Path is not safe for xargs.%{rs}\n", ftwbuf->path);
+ state.action = BFTW_SKIP_SUBTREE;
+ goto done;
+ }
+
if (ftwbuf->depth >= cmdline->maxdepth) {
state.action = BFTW_SKIP_SUBTREE;
}
diff --git a/parse.c b/parse.c
index 193278a..ced1306 100644
--- a/parse.c
+++ b/parse.c
@@ -744,6 +744,14 @@ static struct expr *parse_follow(struct parser_state *state, int flags, int opti
}
/**
+ * Parse -X.
+ */
+static struct expr *parse_xargs_safe(struct parser_state *state, int arg1, int arg2) {
+ state->cmdline->xargs_safe = true;
+ return parse_nullary_flag(state);
+}
+
+/**
* Parse -executable, -readable, -writable
*/
static struct expr *parse_access(struct parser_state *state, int flag, int arg2) {
@@ -1946,6 +1954,7 @@ static const struct table_entry parse_table[] = {
{"P", false, parse_follow, 0, false},
{"H", false, parse_follow, BFTW_COMFOLLOW, false},
{"L", false, parse_follow, BFTW_LOGICAL | BFTW_DETECT_CYCLES, false},
+ {"X", false, parse_xargs_safe},
{"a"},
{"amin", false, parse_acmtime, ATIME, MINUTES},
{"and"},
@@ -2627,6 +2636,7 @@ struct cmdline *parse_cmdline(int argc, char *argv[]) {
cmdline->flags = BFTW_RECOVER;
cmdline->optlevel = 3;
cmdline->debug = 0;
+ cmdline->xargs_safe = false;
cmdline->ignore_races = false;
cmdline->expr = &expr_true;
cmdline->nopen_files = 0;
diff --git a/tests.sh b/tests.sh
index db223ab..61aab2a 100755
--- a/tests.sh
+++ b/tests.sh
@@ -88,6 +88,8 @@ function make_weirdnames() {
touchp "$1/,/f"
touchp "$1/)/g"
touchp "$1/.../h"
+ touchp "$1/\\/i"
+ touchp "$1/ /j"
}
make_weirdnames "$TMP/weirdnames"
@@ -162,6 +164,7 @@ posix_tests=(
bsd_tests=(
test_P
test_P_slash
+ test_X
test_follow
test_samefile
test_name_slash
@@ -548,6 +551,10 @@ function test_L() {
bfs_diff -L links 2>/dev/null
}
+function test_X() {
+ bfs_diff -X weirdnames 2>/dev/null
+}
+
function test_follow() {
bfs_diff links -follow 2>/dev/null
}
diff --git a/tests/test_X.out b/tests/test_X.out
new file mode 100644
index 0000000..008297b
--- /dev/null
+++ b/tests/test_X.out
@@ -0,0 +1,17 @@
+weirdnames
+weirdnames/!
+weirdnames/!-
+weirdnames/(
+weirdnames/(-
+weirdnames/)
+weirdnames/,
+weirdnames/-
+weirdnames/...
+weirdnames/!-/e
+weirdnames/!/d
+weirdnames/(-/c
+weirdnames/(/b
+weirdnames/)/g
+weirdnames/,/f
+weirdnames/-/a
+weirdnames/.../h
diff --git a/tests/test_follow_comma.out b/tests/test_follow_comma.out
index a4d5860..8b90e76 100644
--- a/tests/test_follow_comma.out
+++ b/tests/test_follow_comma.out
@@ -1,4 +1,5 @@
.
+./
./!
./!-
./(
@@ -7,6 +8,8 @@
./,
./-
./...
+./\
+./ /j
./!-/e
./!/d
./(-/c
@@ -15,3 +18,4 @@
./,/f
./-/a
./.../h
+./\/i
diff --git a/tests/test_nohidden.out b/tests/test_nohidden.out
index e505d02..d2a9690 100644
--- a/tests/test_nohidden.out
+++ b/tests/test_nohidden.out
@@ -1,4 +1,5 @@
weirdnames
+weirdnames/
weirdnames/!
weirdnames/!-
weirdnames/(
@@ -6,6 +7,8 @@ weirdnames/(-
weirdnames/)
weirdnames/,
weirdnames/-
+weirdnames/\
+weirdnames/ /j
weirdnames/!-/e
weirdnames/!/d
weirdnames/(-/c
@@ -13,3 +16,4 @@ weirdnames/(/b
weirdnames/)/g
weirdnames/,/f
weirdnames/-/a
+weirdnames/\/i