@matheusbsbs / matheus-bagliano / commits / ef00d150e4
Fork 0

Tighten refspec processing

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@iabervon.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Daniel Barkalow committed Mar 17, 2008 at 22:05 UTC ef00d150e4f9959bf083adf92419b5053ba11584
1 file changed +38 -9
remote.c
+38 -9
@@ -396,6 +396,7 @@ static void read_config(void)
396 struct refspec *parse_ref_spec(int nr_refspec, const char **refspec)
397 {
398 int i;
399 + int st;
400 struct refspec *rs = xcalloc(sizeof(*rs), nr_refspec);
401 for (i = 0; i < nr_refspec; i++) {
402 const char *sp, *ep, *gp;
@@ -404,13 +405,15 @@ struct refspec *parse_ref_spec(int nr_refspec, const char **refspec)
405 rs[i].force = 1;
406 sp++;
407 }
407 - gp = strchr(sp, '*');
408 + gp = strstr(sp, "/*");
409 ep = strchr(sp, ':');
410 if (gp && ep && gp > ep)
411 gp = NULL;
412 if (ep) {
413 if (ep[1]) {
413 - const char *glob = strchr(ep + 1, '*');
414 + const char *glob = strstr(ep + 1, "/*");
415 + if (glob && glob[2])
416 + glob = NULL;
417 if (!glob)
418 gp = NULL;
419 if (gp)
@@ -422,11 +425,24 @@ struct refspec *parse_ref_spec(int nr_refspec, const char **refspec)
425 } else {
426 ep = sp + strlen(sp);
427 }
428 + if (gp && gp + 2 != ep)
429 + gp = NULL;
430 if (gp) {
431 rs[i].pattern = 1;
432 ep = gp;
433 }
434 rs[i].src = xstrndup(sp, ep - sp);
435 +
436 + if (*rs[i].src) {
437 + st = check_ref_format(rs[i].src);
438 + if (st && st != CHECK_REF_FORMAT_ONELEVEL)
439 + die("Invalid refspec '%s'", refspec[i]);
440 + }
441 + if (rs[i].dst && *rs[i].dst) {
442 + st = check_ref_format(rs[i].dst);
443 + if (st && st != CHECK_REF_FORMAT_ONELEVEL)
444 + die("Invalid refspec '%s'", refspec[i]);
445 + }
446 }
447 return rs;
448 }
@@ -543,7 +559,8 @@ int remote_find_tracking(struct remote *remote, struct refspec *refspec)
559 if (!fetch->dst)
560 continue;
561 if (fetch->pattern) {
546 - if (!prefixcmp(needle, key)) {
562 + if (!prefixcmp(needle, key) &&
563 + needle[strlen(key)] == '/') {
564 *result = xmalloc(strlen(value) +
565 strlen(needle) -
566 strlen(key) + 1);
@@ -790,7 +807,9 @@ static const struct refspec *check_pattern_match(const struct refspec *rs,
807 {
808 int i;
809 for (i = 0; i < rs_nr; i++) {
793 - if (rs[i].pattern && !prefixcmp(src->name, rs[i].src))
810 + if (rs[i].pattern &&
811 + !prefixcmp(src->name, rs[i].src) &&
812 + src->name[strlen(rs[i].src)] == '/')
813 return rs + i;
814 }
815 return NULL;
@@ -989,7 +1008,7 @@ int get_fetch_map(const struct ref *remote_refs,
1008 struct ref ***tail,
1009 int missing_ok)
1010 {
992 - struct ref *ref_map, *rm;
1011 + struct ref *ref_map, **rmp;
1012
1013 if (refspec->pattern) {
1014 ref_map = get_expanded_map(remote_refs, refspec);
@@ -1006,10 +1025,20 @@ int get_fetch_map(const struct ref *remote_refs,
1025 }
1026 }
1027
1009 - for (rm = ref_map; rm; rm = rm->next) {
1010 - if (rm->peer_ref && check_ref_format(rm->peer_ref->name + 5))
1011 - die("* refusing to create funny ref '%s' locally",
1012 - rm->peer_ref->name);
1028 + for (rmp = &ref_map; *rmp; ) {
1029 + if ((*rmp)->peer_ref) {
1030 + int st = check_ref_format((*rmp)->peer_ref->name + 5);
1031 + if (st && st != CHECK_REF_FORMAT_ONELEVEL) {
1032 + struct ref *ignore = *rmp;
1033 + error("* Ignoring funny ref '%s' locally",
1034 + (*rmp)->peer_ref->name);
1035 + *rmp = (*rmp)->next;
1036 + free(ignore->peer_ref);
1037 + free(ignore);
1038 + continue;
1039 + }
1040 + }
1041 + rmp = &((*rmp)->next);
1042 }
1043
1044 if (ref_map)