>From e7641882e3ef373b6c58bcf27fbc49269e2541f3 Mon Sep 17 00:00:00 2001
From: James Youngman <[email protected]>
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