find: fix handling of trailing slashes in -name PATTERN comparisons

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
diff --git a/findutils/find.c b/findutils/find.c
index d71c697..27698e5 100644
--- a/findutils/find.c
+++ b/findutils/find.c
@@ -502,26 +502,54 @@
 
 ACTF(name)
 {
+	int r;
 	const char *tmp = bb_basename(fileName);
-	if (tmp != fileName && *tmp == '\0') {
-		/* "foo/bar/". Oh no... go back to 'b' */
-		tmp--;
-		while (tmp != fileName && *--tmp != '/')
-			continue;
-		if (*tmp == '/')
-			tmp++;
+	/* GNU findutils: find DIR/ -name DIR
+	 * prints "DIR/" (DIR// prints "DIR//" etc).
+	 * Need to strip trailing "/".
+	 * Such names can come only from top-level names, but
+	 * we can't do this before recursive_action() call,
+	 * since then "find FILE/ -name FILE"
+	 * would also work (on non-directories), which is wrong.
+	 */
+	char *trunc_slash = NULL;
+
+	if (*tmp == '\0') {
+		/* "foo/bar/[//...]" */
+		while (tmp != fileName && tmp[-1] == '/')
+			tmp--;
+		if (tmp == fileName) { /* entire fileName is "//.."? */
+			/* yes, convert "//..." to "/"
+			 * Testcases:
+			 * find / -maxdepth 1 -name /: prints /
+			 * find // -maxdepth 1 -name /: prints //
+			 * find / -maxdepth 1 -name //: prints nothing
+			 * find // -maxdepth 1 -name //: prints nothing
+			 */
+			if (tmp[1])
+				trunc_slash = (char*)tmp + 1;
+		} else {
+			/* no, it's "foo/bar/[//...]", go back to 'b' */
+			trunc_slash = (char*)tmp;
+			while (tmp != fileName && tmp[-1] != '/')
+				tmp--;
+		}
 	}
+
 	/* Was using FNM_PERIOD flag too,
 	 * but somewhere between 4.1.20 and 4.4.0 GNU find stopped using it.
 	 * find -name '*foo' should match .foo too:
 	 */
+	if (trunc_slash) *trunc_slash = '\0';
 #if FNM_CASEFOLD
-	return fnmatch(ap->pattern, tmp, (ap->iname ? FNM_CASEFOLD : 0)) == 0;
+	r = fnmatch(ap->pattern, tmp, (ap->iname ? FNM_CASEFOLD : 0));
 #else
 	if (ap->iname)
 		tmp = strcpy_upcase(alloca(strlen(tmp) + 1), tmp);
-	return fnmatch(ap->pattern, tmp, 0) == 0;
+	r = fnmatch(ap->pattern, tmp, 0);
 #endif
+	if (trunc_slash) *trunc_slash = '/';
+	return r == 0;
 }
 
 #if ENABLE_FEATURE_FIND_PATH