[PATCH] Tighten refspec processing

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This changes the pattern matching code to not store the required final
/ before the *, and then to require each side to be a valid ref (or
empty). In particular, any refspec that looks like it should be a
pattern but doesn't quite meet the requirements will be found to be
invalid as a fallback non-pattern.

Signed-off-by: Daniel Barkalow <barkalow@xxxxxxxxxxxx>
---
(replaces the earlier patch)

 remote.c |   47 ++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 38 insertions(+), 9 deletions(-)

diff --git a/remote.c b/remote.c
index f3f7375..476b8ef 100644
--- a/remote.c
+++ b/remote.c
@@ -396,6 +396,7 @@ static void read_config(void)
 struct refspec *parse_ref_spec(int nr_refspec, const char **refspec)
 {
 	int i;
+	int st;
 	struct refspec *rs = xcalloc(sizeof(*rs), nr_refspec);
 	for (i = 0; i < nr_refspec; i++) {
 		const char *sp, *ep, *gp;
@@ -404,13 +405,15 @@ struct refspec *parse_ref_spec(int nr_refspec, const char **refspec)
 			rs[i].force = 1;
 			sp++;
 		}
-		gp = strchr(sp, '*');
+		gp = strstr(sp, "/*");
 		ep = strchr(sp, ':');
 		if (gp && ep && gp > ep)
 			gp = NULL;
 		if (ep) {
 			if (ep[1]) {
-				const char *glob = strchr(ep + 1, '*');
+				const char *glob = strstr(ep + 1, "/*");
+				if (glob && glob[2])
+					glob = NULL;
 				if (!glob)
 					gp = NULL;
 				if (gp)
@@ -422,11 +425,24 @@ struct refspec *parse_ref_spec(int nr_refspec, const char **refspec)
 		} else {
 			ep = sp + strlen(sp);
 		}
+		if (gp && gp + 2 != ep)
+			gp = NULL;
 		if (gp) {
 			rs[i].pattern = 1;
 			ep = gp;
 		}
 		rs[i].src = xstrndup(sp, ep - sp);
+
+		if (*rs[i].src) {
+			st = check_ref_format(rs[i].src);
+			if (st && st != CHECK_REF_FORMAT_ONELEVEL)
+				die("Invalid refspec '%s'", refspec[i]);
+		}
+		if (rs[i].dst && *rs[i].dst) {
+			st = check_ref_format(rs[i].dst);
+			if (st && st != CHECK_REF_FORMAT_ONELEVEL)
+				die("Invalid refspec '%s'", refspec[i]);
+		}
 	}
 	return rs;
 }
@@ -543,7 +559,8 @@ int remote_find_tracking(struct remote *remote, struct refspec *refspec)
 		if (!fetch->dst)
 			continue;
 		if (fetch->pattern) {
-			if (!prefixcmp(needle, key)) {
+			if (!prefixcmp(needle, key) &&
+			    needle[strlen(key)] == '/') {
 				*result = xmalloc(strlen(value) +
 						  strlen(needle) -
 						  strlen(key) + 1);
@@ -790,7 +807,9 @@ static const struct refspec *check_pattern_match(const struct refspec *rs,
 {
 	int i;
 	for (i = 0; i < rs_nr; i++) {
-		if (rs[i].pattern && !prefixcmp(src->name, rs[i].src))
+		if (rs[i].pattern && 
+		    !prefixcmp(src->name, rs[i].src) &&
+		    src->name[strlen(rs[i].src)] == '/')
 			return rs + i;
 	}
 	return NULL;
@@ -989,7 +1008,7 @@ int get_fetch_map(const struct ref *remote_refs,
 		  struct ref ***tail,
 		  int missing_ok)
 {
-	struct ref *ref_map, *rm;
+	struct ref *ref_map, **rmp;
 
 	if (refspec->pattern) {
 		ref_map = get_expanded_map(remote_refs, refspec);
@@ -1006,10 +1025,20 @@ int get_fetch_map(const struct ref *remote_refs,
 		}
 	}
 
-	for (rm = ref_map; rm; rm = rm->next) {
-		if (rm->peer_ref && check_ref_format(rm->peer_ref->name + 5))
-			die("* refusing to create funny ref '%s' locally",
-			    rm->peer_ref->name);
+	for (rmp = &ref_map; *rmp; ) {
+		if ((*rmp)->peer_ref) {
+			int st = check_ref_format((*rmp)->peer_ref->name + 5);
+			if (st && st != CHECK_REF_FORMAT_ONELEVEL) {
+				struct ref *ignore = *rmp;
+				error("* Ignoring funny ref '%s' locally",
+				      (*rmp)->peer_ref->name);
+				*rmp = (*rmp)->next;
+				free(ignore->peer_ref);
+				free(ignore);
+				continue;
+			}
+		}
+		rmp = &((*rmp)->next);
 	}
 
 	if (ref_map)
-- 
1.5.4.3.610.gea6cd
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux