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

[PATCH 13/45] Guard against new pathspec magic in pathspec matching code

From
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date
Jun 9, 2013, 06:25 UTC
Message-ID
<1370759178-1709-14-git-send-email-pclouds@gmail.com>
In-Reply-To
<1370759178-1709-1-git-send-email-pclouds@gmail.com>

GUARD_PATHSPEC() marks pathspec-sensitive code, basically all those that touch anything in 'struct pathspec' except fields "nr" and "original". GUARD_PATHSPEC() is not supposed to fail. It's mainly to help the designers to catch unsupported codepaths.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 Documentation/technical/api-setup.txt | 19 +++++++++++++++++++
 builtin/diff.c                        |  2 ++
 dir.c                                 |  2 ++
 pathspec.h                            |  7 +++++++
 tree-diff.c                           | 19 +++++++++++++++++++
 tree-walk.c                           |  2 ++
 6 files changed, 51 insertions(+)
diff --git a/Documentation/technical/api-setup.txt b/Documentation/technical/api-setup.txt
index 90d1aff..540e455 100644
--- a/Documentation/technical/api-setup.txt
+++ b/Documentation/technical/api-setup.txt
@@ -28,3 +28,22 @@ parse_pathspec(). This function takes several arguments:
 - prefix and args come from cmd_* functions
 
 get_pathspec() is obsolete and should never be used in new code.
+
+parse_pathspec() helps catch unsupported features and reject them
+politely. At a lower level, different pathspec-related functions may
+not support the same set of features. Such pathspec-sensitive
+functions are guarded with GUARD_PATHSPEC(), which will die in an
+unfriendly way when an unsupported feature is requested.
+
+The command designers are supposed to make sure that GUARD_PATHSPEC()
+never dies. They have to make sure all unsupported features are caught
+by parse_pathspec(), not by GUARD_PATHSPEC. grepping GUARD_PATHSPEC()
+should give the designers all pathspec-sensitive codepaths and what
+features they support.
+
+A similar process is applied when a new pathspec magic is added. The
+designer lifts the GUARD_PATHSPEC restriction in the functions that
+support the new magic. At the same time (s)he has to make sure this
+new feature will be caught at parse_pathspec() in commands that cannot
+handle the new magic in some cases. grepping parse_pathspec() should
+help.
diff --git a/builtin/diff.c b/builtin/diff.c
index 8c2af6c..d237e0a 100644
--- a/builtin/diff.c
+++ b/builtin/diff.c
@@ -371,6 +371,8 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
 		die(_("unhandled object '%s' given."), name);
 	}
 	if (rev.prune_data.nr) {
+		/* builtin_diff_b_f() */
+		GUARD_PATHSPEC(&rev.prune_data, PATHSPEC_FROMTOP);
 		if (!path)
 			path = rev.prune_data.items[0].match;
 		paths += rev.prune_data.nr;
diff --git a/dir.c b/dir.c
index cfcdda5..fcc0b97 100644
--- a/dir.c
+++ b/dir.c
@@ -340,6 +340,8 @@ int match_pathspec_depth(const struct pathspec *ps,
 {
 	int i, retval = 0;
 
+	GUARD_PATHSPEC(ps, PATHSPEC_FROMTOP | PATHSPEC_MAXDEPTH);
+
 	if (!ps->nr) {
 		if (!ps->recursive ||
 		    !(ps->magic & PATHSPEC_MAXDEPTH) ||
diff --git a/pathspec.h b/pathspec.h
index 3ca6636..7068f7d 100644
--- a/pathspec.h
+++ b/pathspec.h
@@ -27,6 +27,13 @@ struct pathspec {
 	} *items;
 };
 
+#define GUARD_PATHSPEC(ps, mask) \
+	do { \
+		if ((ps)->magic & ~(mask))	       \
+			die("BUG:%s:%d: unsupported magic %x",	\
+			    __FILE__, __LINE__, (ps)->magic & ~(mask)); \
+	} while (0)
+
 /* parse_pathspec flags */
 #define PATHSPEC_PREFER_CWD (1<<0) /* No args means match cwd */
 #define PATHSPEC_PREFER_FULL (1<<1) /* No args means match everything */
diff --git a/tree-diff.c b/tree-diff.c
index 826512e..5a87614 100644
--- a/tree-diff.c
+++ b/tree-diff.c
@@ -198,6 +198,25 @@ static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, co
 	const char *paths[1];
 	int i;
 
+	/*
+	 * follow-rename code is very specific, we need exactly one
+	 * path. Magic that matches more than one path is not
+	 * supported.
+	 */
+	GUARD_PATHSPEC(&opt->pathspec, PATHSPEC_FROMTOP);
+#if 0
+	/*
+	 * We should reject wildcards as well. Unfortunately we
+	 * haven't got a reliable way to detect that 'foo\*bar' in
+	 * fact has no wildcards. nowildcard_len is merely a hint for
+	 * optimization. Let it slip for now until wildmatch is taught
+	 * about dry-run mode and returns wildcard info.
+	 */
+	if (opt->pathspec.has_wildcard)
+		die("BUG:%s:%d: wildcards are not supported",
+		    __FILE__, __LINE__);
+#endif
+
 	/* Remove the file creation entry from the diff queue, and remember it */
 	choice = q->queue[0];
 	q->nr = 0;
diff --git a/tree-walk.c b/tree-walk.c
index d399ca9..37b157e 100644
--- a/tree-walk.c
+++ b/tree-walk.c
@@ -636,6 +636,8 @@ enum interesting tree_entry_interesting(const struct name_entry *entry,
 	enum interesting never_interesting = ps->has_wildcard ?
 		entry_not_interesting : all_entries_not_interesting;
 
+	GUARD_PATHSPEC(ps, PATHSPEC_FROMTOP | PATHSPEC_MAXDEPTH);
+
 	if (!ps->nr) {
 		if (!ps->recursive ||
 		    !(ps->magic & PATHSPEC_MAXDEPTH) ||
-- 
1.8.2.83.gc99314b
Previous: Eric SunshineNext: Eric Sunshine
Message 21 of 54 in “"struct pathspec" conversion and :(glob)”
  1. 00/45 "struct pathspec" conversion and :(glob)Nguyễn Thái Ngọc Duy, Jun 9, 2013
  2. 01/45 clean: remove unused variable "seen"Nguyễn Thái Ngọc Duy, Jun 9, 2013
  3. 02/45 Move struct pathspec and related functions to pathspec.[ch]Nguyễn Thái Ngọc Duy, Jun 9, 2013
  4. 03/45 pathspec: i18n-ize error strings in pathspec parsing codeNguyễn Thái Ngọc Duy, Jun 9, 2013
  5. 04/45 pathspec: add copy_pathspecNguyễn Thái Ngọc Duy, Jun 9, 2013
  6. Eric SunshineJun 9, 2013
  7. Junio C HamanoJun 12, 2013
  8. 05/45 Add parse_pathspec() that converts cmdline args to struct pathspecNguyễn Thái Ngọc Duy, Jun 9, 2013
  9. Eric SunshineJun 10, 2013
  10. 06/45 parse_pathspec: save original pathspec for reportingNguyễn Thái Ngọc Duy, Jun 9, 2013
  11. 07/45 parse_pathspec: add PATHSPEC_PREFER_{CWD,FULL}Nguyễn Thái Ngọc Duy, Jun 9, 2013
  12. Eric SunshineJun 10, 2013
  13. 08/45 Convert some get_pathspec() calls to parse_pathspec()Nguyễn Thái Ngọc Duy, Jun 9, 2013
  14. 09/45 parse_pathspec: a special flag for max_depth featureNguyễn Thái Ngọc Duy, Jun 9, 2013
  15. Eric SunshineJun 10, 2013
  16. 10/45 parse_pathspec: support stripping submodule trailing slashesNguyễn Thái Ngọc Duy, Jun 9, 2013
  17. Eric SunshineJun 10, 2013
  18. 11/45 parse_pathspec: support stripping/checking submodule pathsNguyễn Thái Ngọc Duy, Jun 9, 2013
  19. 12/45 parse_pathspec: support prefixing original patternsNguyễn Thái Ngọc Duy, Jun 9, 2013
  20. Eric SunshineJun 10, 2013
  21. 13/45 Guard against new pathspec magic in pathspec matching codeNguyễn Thái Ngọc Duy, Jun 9, 2013
  22. Eric SunshineJun 10, 2013
  23. 14/45 clean: convert to use parse_pathspecNguyễn Thái Ngọc Duy, Jun 9, 2013
  24. 15/45 commit: convert to use parse_pathspecNguyễn Thái Ngọc Duy, Jun 9, 2013
  25. 16/45 status: convert to use parse_pathspecNguyễn Thái Ngọc Duy, Jun 9, 2013
  26. 17/45 rerere: convert to use parse_pathspecNguyễn Thái Ngọc Duy, Jun 9, 2013
  27. 18/45 checkout: convert to use parse_pathspecNguyễn Thái Ngọc Duy, Jun 9, 2013
  28. 19/45 rm: convert to use parse_pathspecNguyễn Thái Ngọc Duy, Jun 9, 2013
  29. 20/45 ls-files: convert to use parse_pathspecNguyễn Thái Ngọc Duy, Jun 9, 2013
  30. 21/45 archive: convert to use parse_pathspecNguyễn Thái Ngọc Duy, Jun 9, 2013
  31. 22/45 check-ignore: convert to use parse_pathspecNguyễn Thái Ngọc Duy, Jun 9, 2013
  32. 23/45 add: convert to use parse_pathspecNguyễn Thái Ngọc Duy, Jun 9, 2013
  33. 24/45 reset: convert to use parse_pathspecNguyễn Thái Ngọc Duy, Jun 9, 2013
  34. 25/45 line-log: convert to use parse_pathspecNguyễn Thái Ngọc Duy, Jun 9, 2013
  35. 26/45 Convert read_cache_preload() to take struct pathspecNguyễn Thái Ngọc Duy, Jun 9, 2013
  36. 27/45 Convert run_add_interactive to use struct pathspecNguyễn Thái Ngọc Duy, Jun 9, 2013
  37. 28/45 Convert unmerge_cache to take struct pathspecNguyễn Thái Ngọc Duy, Jun 9, 2013
  38. 29/45 checkout: convert read_tree_some to take struct pathspecNguyễn Thái Ngọc Duy, Jun 9, 2013
  39. 30/45 Convert report_path_error to take struct pathspecNguyễn Thái Ngọc Duy, Jun 9, 2013
  40. 31/45 Convert refresh_index to take struct pathspecNguyễn Thái Ngọc Duy, Jun 9, 2013
  41. 32/45 Convert {read,fill}_directory to take struct pathspecNguyễn Thái Ngọc Duy, Jun 9, 2013
  42. 33/45 Convert add_files_to_cache to take struct pathspecNguyễn Thái Ngọc Duy, Jun 9, 2013
  43. 34/45 Convert common_prefix() to use struct pathspecNguyễn Thái Ngọc Duy, Jun 9, 2013
  44. 35/45 Remove diff_tree_{setup,release}_pathsNguyễn Thái Ngọc Duy, Jun 9, 2013
  45. 36/45 Remove init_pathspec() in favor of parse_pathspec()Nguyễn Thái Ngọc Duy, Jun 9, 2013
  46. 37/45 Remove match_pathspec() in favor of match_pathspec_depth()Nguyễn Thái Ngọc Duy, Jun 9, 2013
  47. 38/45 tree-diff: remove the use of pathspec's raw[] in follow-rename codepathNguyễn Thái Ngọc Duy, Jun 9, 2013
  48. 39/45 parse_pathspec: make sure the prefix part is wildcard-freeNguyễn Thái Ngọc Duy, Jun 9, 2013
  49. 40/45 parse_pathspec: preserve prefix length via PATHSPEC_PREFIX_ORIGINNguyễn Thái Ngọc Duy, Jun 9, 2013
  50. 41/45 Kill limit_pathspec_to_literal() as it's only used by parse_pathspec()Nguyễn Thái Ngọc Duy, Jun 9, 2013
  51. 42/45 pathspec: support :(literal) syntax for noglob pathspecNguyễn Thái Ngọc Duy, Jun 9, 2013
  52. 43/45 pathspec: make --literal-pathspecs disable pathspec magicNguyễn Thái Ngọc Duy, Jun 9, 2013
  53. 44/45 pathspec: support :(glob) syntaxNguyễn Thái Ngọc Duy, Jun 9, 2013
  54. 45/45 Rename field "raw" to "_raw" in struct pathspecNguyễn Thái Ngọc Duy, Jun 9, 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.