[git commit] find: fix a regression introduced with -HLP support

Denys Vlasenko vda.linux at googlemail.com
Thu Jan 9 15:08:09 UTC 2014


commit: http://git.busybox.net/busybox/commit/?id=6eb0cbe07e5c2f3131c2d6a5bafd83d2cac20f7d
branch: http://git.busybox.net/busybox/commit/?id=refs/heads/master

function                                             old     new   delta
find_main                                            294     342     +48

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 findutils/find.c     |   21 ++++++++++++++++++++-
 testsuite/find.tests |   22 ++++++++++++++++++++++
 2 files changed, 42 insertions(+), 1 deletions(-)

diff --git a/findutils/find.c b/findutils/find.c
index 53d8239..5d5e24b 100644
--- a/findutils/find.c
+++ b/findutils/find.c
@@ -1291,9 +1291,27 @@ int find_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int find_main(int argc UNUSED_PARAM, char **argv)
 {
 	int i, firstopt, status = EXIT_SUCCESS;
+	char **past_HLP, *saved;
 
 	INIT_G();
 
+	/* "find -type f" + getopt("+HLP") => disaster.
+	 * Need to avoid getopt running into a non-HLP option.
+	 * Do this by temporarily storing NULL there:
+	 */
+	past_HLP = argv;
+	for (;;) {
+		saved = *++past_HLP;
+		if (!saved)
+			break;
+		if (saved[0] != '-')
+			break;
+		if (!saved[1])
+			break; /* it is "-" */
+		if ((saved+1)[strspn(saved+1, "HLP")] != '\0')
+			break;
+	}
+	*past_HLP = NULL;
 	/* "+": stop on first non-option */
 	i = getopt32(argv, "+HLP");
 	if (i & (1<<0))
@@ -1301,7 +1319,8 @@ int find_main(int argc UNUSED_PARAM, char **argv)
 	if (i & (1<<1))
 		G.recurse_flags |= ACTION_FOLLOWLINKS | ACTION_DANGLING_OK;
 	/* -P is default and is ignored */
-	argv += optind;
+	argv = past_HLP; /* same result as "argv += optind;" */
+	*past_HLP = saved;
 
 	for (firstopt = 0; argv[firstopt]; firstopt++) {
 		if (argv[firstopt][0] == '-')
diff --git a/testsuite/find.tests b/testsuite/find.tests
new file mode 100755
index 0000000..345d1e8
--- /dev/null
+++ b/testsuite/find.tests
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+# Copyright 2014 by Denys Vlasenko <vda.linux at googlemail.com>
+# Licensed under GPLv2, see file LICENSE in this source tree.
+
+. ./testing.sh
+
+# testing "description" "command" "result" "infile" "stdin"
+
+mkdir -p find.tempdir
+touch find.tempdir/testfile
+
+testing "find -type f" \
+	"cd find.tempdir && find -type f 2>&1" \
+	"./testfile\n" \
+	"" ""
+
+# testing "description" "command" "result" "infile" "stdin"
+
+rm -rf find.tempdir
+
+exit $FAILCOUNT


More information about the busybox-cvs mailing list