>From e7641882e3ef373b6c58bcf27fbc49269e2541f3 Mon Sep 17 00:00:00 2001 From: James Youngman <ja...@youngman.org> Date: Thu, 31 Oct 2024 15:06:02 +0000 Subject: [PATCH] [find] Fix Savannah bug 66365.
A "+" only terminates -exec when it immediately follows an argument which is exactly "{}". --- find/parser.c | 21 ++++++++++++------- find/testsuite/Makefile.am | 2 ++ .../find.posix/sv-bug-66365-exec.exp | 5 +++++ .../testsuite/find.posix/sv-bug-66365-exec.xo | 1 + 4 files changed, 22 insertions(+), 7 deletions(-) create mode 100644 find/testsuite/find.posix/sv-bug-66365-exec.exp create mode 100644 find/testsuite/find.posix/sv-bug-66365-exec.xo diff --git a/find/parser.c b/find/parser.c index ad3b9904..d7b07c40 100644 --- a/find/parser.c +++ b/find/parser.c @@ -2770,7 +2770,7 @@ insert_exec_ok (const char *action, { int start, end; /* Indexes in ARGV of start & end of cmd. */ int i; /* Index into cmd args */ - int saw_braces; /* True if previous arg was '{}'. */ + bool plus_is_terminator; /* True if previous arg was '{}'. */ bool allow_plus; /* True if + is a valid terminator */ int brace_count; /* Number of instances of {}. */ const char *brace_arg; /* Which arg did {} appear in? */ @@ -2827,24 +2827,31 @@ insert_exec_ok (const char *action, * Also figure out if the command is terminated by ";" or by "+". */ start = *arg_ptr; - for (end = start, saw_braces=0, brace_count=0, brace_arg=NULL; + for (end = start, plus_is_terminator=false, brace_count=0, brace_arg=NULL; (argv[end] != NULL) && ((argv[end][0] != ';') || (argv[end][1] != '\0')); end++) { /* For -exec and -execdir, "{} +" can terminate the command. */ - if ( allow_plus - && argv[end][0] == '+' && argv[end][1] == 0 - && saw_braces) + if (allow_plus && plus_is_terminator + && argv[end][0] == '+' && argv[end][1] == 0) { our_pred->args.exec_vec.multiple = 1; break; } - saw_braces = 0; + plus_is_terminator = false; if (mbsstr (argv[end], "{}")) { - saw_braces = 1; + if (0 == strcmp(argv[end], "{}")) + { + /* Savannah bug 66365: + only terminates the predicate + * immediately after an argument which is exactly, "{}". + * However, the "{}" in "x{}" should get expanded for + * the ";" case. + */ + plus_is_terminator = true; + } brace_arg = argv[end]; ++brace_count; diff --git a/find/testsuite/Makefile.am b/find/testsuite/Makefile.am index ed2962a2..ffa5749c 100644 --- a/find/testsuite/Makefile.am +++ b/find/testsuite/Makefile.am @@ -105,6 +105,7 @@ find.posix/sv-bug-11175.xo \ find.posix/sv-bug-12181.xo \ find.posix/sv-bug-25359.xo \ find.posix/sv-bug-27563-exec.xo \ +find.posix/sv-bug-66365-exec.xo \ find.posix/mtime0.xo \ find.posix/sizes.xo \ find.posix/name.xo \ @@ -245,6 +246,7 @@ find.posix/sv-bug-15235.exp \ find.posix/sv-bug-19605.exp \ find.posix/sv-bug-19613.exp \ find.posix/sv-bug-19617.exp \ +find.posix/sv-bug-66365-exec.exp \ find.posix/typesize.exp \ find.posix/user-empty.exp \ find.posix/user-missing.exp diff --git a/find/testsuite/find.posix/sv-bug-66365-exec.exp b/find/testsuite/find.posix/sv-bug-66365-exec.exp new file mode 100644 index 00000000..ef88762e --- /dev/null +++ b/find/testsuite/find.posix/sv-bug-66365-exec.exp @@ -0,0 +1,5 @@ +# tests for Savannah bug 66365 (result of find . -prune -exec echo x{} + \;) +exec rm -rf tmp +exec mkdir tmp +find_start p {tmp -prune -exec echo x\{\} + \; } +exec rm -rf tmp diff --git a/find/testsuite/find.posix/sv-bug-66365-exec.xo b/find/testsuite/find.posix/sv-bug-66365-exec.xo new file mode 100644 index 00000000..eb46b7d3 --- /dev/null +++ b/find/testsuite/find.posix/sv-bug-66365-exec.xo @@ -0,0 +1 @@ +xtmp + -- 2.39.5