git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [regression?] trailing slash required in .gitattributes

From
Duy Nguyen <pclouds@gmail.com>
Date
Mar 23, 2013, 04:18 UTC
Message-ID
<20130323041824.GA11142@lanh>
In-Reply-To
<20130322222438.GA13207@sigill.intra.peff.net>
On Fri, Mar 22, 2013 at 06:24:39PM -0400, Jeff King wrote:
> I'm having trouble figuring out the right solution for this.

Thanks for looking into this. It was on my todo list, but you beat me to it :)

Show 13 quoted lines
> But then here we'll end up feeding "foo/" to be compared with "foo",
> which we don't want. For a pattern "foo", we want to match _either_
> "foo/" or "foo". So you'd think something like:
> 
>   if (pathlen && pathname[pathlen-1] == '/')
>           pathlen--;
> 
> would work. But it seems that match_basename, despite taking the length
> of all of the strings we pass it, will happily use NUL-terminated
> functions like strcmp or fnmatch. Converting the former to check lengths
> should be pretty straightforward. But there is no version of fnmatch
> that does what we want. I wonder if we using wildmatch can get around
> this limitation.

You can use nwildmatch() from this patch. I tested it lightly with t3070-wildmatch.sh, feeding the strings with no terminating NUL. It seems to work ok.

-- 8< --
Subject: [PATCH] wildmatch: do not require "text" to be NUL-terminated

This may be helpful when we just want to match a part of "text". nwildmatch can be used for this purpose.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 wildmatch.c | 25 +++++++++++++------------
 wildmatch.h | 11 +++++++++--
 2 files changed, 22 insertions(+), 14 deletions(-)
diff --git a/wildmatch.c b/wildmatch.c
index 7192bdc..f97ae2a 100644
--- a/wildmatch.c
+++ b/wildmatch.c
@@ -52,7 +52,8 @@ typedef unsigned char uchar;
 #define ISXDIGIT(c) (ISASCII(c) && isxdigit(c))
 
 /* Match pattern "p" against "text" */
-static int dowild(const uchar *p, const uchar *text, unsigned int flags)
+static int dowild(const uchar *p, const uchar *text,
+		  const uchar *textend, unsigned int flags)
 {
 	uchar p_ch;
 	const uchar *pattern = p;
@@ -60,8 +61,9 @@ static int dowild(const uchar *p, const uchar *text, unsigned int flags)
 	for ( ; (p_ch = *p) != '\0'; text++, p++) {
 		int matched, match_slash, negated;
 		uchar t_ch, prev_ch;
-		if ((t_ch = *text) == '\0' && p_ch != '*')
+		if (text >= textend && p_ch != '*')
 			return WM_ABORT_ALL;
+		t_ch = *text;
 		if ((flags & WM_CASEFOLD) && ISUPPER(t_ch))
 			t_ch = tolower(t_ch);
 		if ((flags & WM_CASEFOLD) && ISUPPER(p_ch))
@@ -101,7 +103,7 @@ static int dowild(const uchar *p, const uchar *text, unsigned int flags)
 					 * both foo/bar and foo/a/bar.
 					 */
 					if (p[0] == '/' &&
-					    dowild(p + 1, text, flags) == WM_MATCH)
+					    dowild(p + 1, text, textend, flags) == WM_MATCH)
 						return WM_MATCH;
 					match_slash = 1;
 				} else
@@ -130,9 +132,7 @@ static int dowild(const uchar *p, const uchar *text, unsigned int flags)
 				/* the slash is consumed by the top-level for loop */
 				break;
 			}
-			while (1) {
-				if (t_ch == '\0')
-					break;
+			while (text < textend) {
 				/*
 				 * Try to advance faster when an asterisk is
 				 * followed by a literal. We know in this case
@@ -145,18 +145,18 @@ static int dowild(const uchar *p, const uchar *text, unsigned int flags)
 					p_ch = *p;
 					if ((flags & WM_CASEFOLD) && ISUPPER(p_ch))
 						p_ch = tolower(p_ch);
-					while ((t_ch = *text) != '\0' &&
+					while (text < textend &&
 					       (match_slash || t_ch != '/')) {
 						if ((flags & WM_CASEFOLD) && ISUPPER(t_ch))
 							t_ch = tolower(t_ch);
 						if (t_ch == p_ch)
 							break;
-						text++;
+						t_ch = *++text;
 					}
 					if (t_ch != p_ch)
 						return WM_NOMATCH;
 				}
-				if ((matched = dowild(p, text, flags)) != WM_NOMATCH) {
+				if ((matched = dowild(p, text, textend, flags)) != WM_NOMATCH) {
 					if (!match_slash || matched != WM_ABORT_TO_STARSTAR)
 						return matched;
 				} else if (!match_slash && t_ch == '/')
@@ -261,12 +261,13 @@ static int dowild(const uchar *p, const uchar *text, unsigned int flags)
 		}
 	}
 
-	return *text ? WM_NOMATCH : WM_MATCH;
+	return text < textend ? WM_NOMATCH : WM_MATCH;
 }
 
 /* Match the "pattern" against the "text" string. */
-int wildmatch(const char *pattern, const char *text,
+int nwildmatch(const char *pattern, const char *text, int textlen,
 	      unsigned int flags, struct wildopts *wo)
 {
-	return dowild((const uchar*)pattern, (const uchar*)text, flags);
+	return dowild((const uchar*)pattern, (const uchar*)text,
+		      (const uchar*)text + textlen, flags);
 }
diff --git a/wildmatch.h b/wildmatch.h
index 4090c8f..cdd7544 100644
--- a/wildmatch.h
+++ b/wildmatch.h
@@ -12,7 +12,14 @@
 
 struct wildopts;
 
-int wildmatch(const char *pattern, const char *text,
-	      unsigned int flags,
+int nwildmatch(const char *pattern, const char *text,
+	      int len, unsigned int flags,
 	      struct wildopts *wo);
+
+/* Match the "pattern" against the "text" string. */
+static inline int wildmatch(const char *pattern, const char *text,
+	      unsigned int flags, struct wildopts *wo)
+{
+	return nwildmatch(pattern, text, strlen(text), flags, wo);
+}
 #endif
-- 
1.8.2.83.gc99314b

-- 8< --
Previous: Jeff KingNext: Duy Nguyen
Message 57 of 66 in “[regression?] trailing slash required in .gitattributes”
  1. Jeff KingMar 19, 2013
  2. Junio C HamanoMar 19, 2013
  3. Jeff KingMar 19, 2013
  4. Jeff KingMar 22, 2013
  5. Junio C HamanoMar 22, 2013
  6. Jeff KingMar 23, 2013
  7. Junio C HamanoMar 24, 2013
  8. 0/4 attribute regression fix for maint-1.8.1 and upwardJunio C Hamano, Mar 26, 2013
  9. 1/4 attr.c::path_matches(): the basename is part of the pathnameJunio C Hamano, Mar 26, 2013
  10. Jeff KingMar 26, 2013
  11. Duy NguyenMar 27, 2013
  12. 2/4 dir.c::match_basename(): pay attention to the length of string parametersJunio C Hamano, Mar 26, 2013
  13. Jeff KingMar 26, 2013
  14. Jeff KingMar 26, 2013
  15. Junio C HamanoMar 26, 2013
  16. Jeff KingMar 26, 2013
  17. Junio C HamanoMar 26, 2013
  18. Jeff KingMar 27, 2013
  19. 3/4 attr.c::path_matches(): special case paths that end with a slashJunio C Hamano, Mar 26, 2013
  20. Jeff KingMar 26, 2013
  21. Jeff KingMar 26, 2013
  22. Duy NguyenMar 27, 2013
  23. Jeff KingMar 28, 2013
  24. 4/4 make sure a pattern without trailing slash matches a directoryJunio C Hamano, Mar 26, 2013
  25. Jeff KingMar 26, 2013
  26. Duy NguyenMar 27, 2013
  27. Junio C HamanoMar 27, 2013
  28. Duy NguyenMar 27, 2013
  29. 0/6 attribute regression fix for maint-1.8.1 and upwardJeff King, Mar 28, 2013
  30. 1/6 attr.c::path_matches(): the basename is part of the pathnameJeff King, Mar 28, 2013
  31. 2/6 dir.c::match_basename(): pay attention to the length of string parametersJeff King, Mar 28, 2013
  32. Jeff KingMar 28, 2013
  33. Jeff KingMar 28, 2013
  34. Junio C HamanoMar 28, 2013
  35. Duy NguyenMar 28, 2013
  36. Duy NguyenMar 29, 2013
  37. Jeff KingMar 29, 2013
  38. Junio C HamanoMar 29, 2013
  39. 3/6 dir.c::match_pathname(): adjust patternlen when shifting patternJeff King, Mar 28, 2013
  40. 4/6 dir.c::match_pathname(): pay attention to the length of string parametersJeff King, Mar 28, 2013
  41. Junio C HamanoMar 28, 2013
  42. Duy NguyenMar 29, 2013
  43. Duy NguyenMar 29, 2013
  44. Torsten BögershausenMar 29, 2013
  45. Duy NguyenMar 29, 2013
  46. Jeff KingMar 29, 2013
  47. Duy NguyenMar 29, 2013
  48. Junio C HamanoMar 29, 2013
  49. Jeff KingMar 29, 2013
  50. Junio C HamanoMar 29, 2013
  51. Jeff KingMar 29, 2013
  52. Duy NguyenMar 30, 2013
  53. 5/6 attr.c::path_matches(): special case paths that end with a slashJeff King, Mar 28, 2013
  54. 6/6 t: check that a pattern without trailing slash matches a directoryJeff King, Mar 28, 2013
  55. Eric SunshineMar 28, 2013
  56. Jeff KingMar 28, 2013
  57. Duy NguyenMar 23, 2013
  58. Duy NguyenMar 23, 2013
  59. 0/4 attr directory matching regressionNguyễn Thái Ngọc Duy, Mar 25, 2013
  60. 1/4 wildmatch: do not require "text" to be NUL-terminatedNguyễn Thái Ngọc Duy, Mar 25, 2013
  61. 2/4 attr.c: fix pattern{,len} inconsistency in struct match_attrNguyễn Thái Ngọc Duy, Mar 25, 2013
  62. 3/4 dir.c: make match_{base,path}name respect {basename,path}lenNguyễn Thái Ngọc Duy, Mar 25, 2013
  63. 4/4 attr.c: fix matching "subdir" without the trailing slashNguyễn Thái Ngọc Duy, Mar 25, 2013
  64. Duy NguyenMar 25, 2013
  65. Duy NguyenMar 25, 2013
  66. Junio C HamanoMar 26, 2013

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.