427
alias_all_urls();
428
}
429
430
+/*
431
+ * We need to make sure the tracking branches are well formed, but a
432
+ * wildcard refspec in "struct refspec" must have a trailing slash. We
433
+ * temporarily drop the trailing '/' while calling check_ref_format(),
434
+ * and put it back. The caller knows that a CHECK_REF_FORMAT_ONELEVEL
435
+ * error return is Ok for a wildcard refspec.
436
+ */
437
+static int verify_refname(char *name, int is_glob)
438
+{
439
+ int result, len = -1;
440
+
441
+ if (is_glob) {
442
+ len = strlen(name);
443
+ assert(name[len - 1] == '/');
444
+ name[len - 1] = '\0';
445
+ }
446
+ result = check_ref_format(name);
447
+ if (is_glob)
448
+ name[len - 1] = '/';
449
+ return result;
450
+}
451
+
452
static struct refspec *parse_refspec_internal(int nr_refspec, const char **refspec, int fetch, int verify)
453
{
454
int i;
456
struct refspec *rs = xcalloc(sizeof(*rs), nr_refspec);
457
458
for (i = 0; i < nr_refspec; i++) {
437
- size_t llen, rlen;
459
+ size_t llen;
460
int is_glob;
461
const char *lhs, *rhs;
462
441
- llen = rlen = is_glob = 0;
463
+ llen = is_glob = 0;
464
465
lhs = refspec[i];
466
if (*lhs == '+') {
480
}
481
482
if (rhs) {
461
- rhs++;
462
- rlen = strlen(rhs);
483
+ size_t rlen = strlen(++rhs);
484
is_glob = (2 <= rlen && !strcmp(rhs + rlen - 2, "/*"));
464
- if (is_glob)
465
- rlen -= 2;
466
- rs[i].dst = xstrndup(rhs, rlen);
485
+ rs[i].dst = xstrndup(rhs, rlen - is_glob);
486
}
487
488
llen = (rhs ? (rhs - lhs - 1) : strlen(lhs));
490
if ((rhs && !is_glob) || (!rhs && fetch))
491
goto invalid;
492
is_glob = 1;
474
- llen -= 2;
493
+ llen--;
494
} else if (rhs && is_glob) {
495
goto invalid;
496
}
507
if (!*rs[i].src)
508
; /* empty is ok */
509
else {
491
- st = check_ref_format(rs[i].src);
510
+ st = verify_refname(rs[i].src, is_glob);
511
if (st && st != CHECK_REF_FORMAT_ONELEVEL)
512
goto invalid;
513
}
522
} else if (!*rs[i].dst) {
523
; /* ok */
524
} else {
506
- st = check_ref_format(rs[i].dst);
525
+ st = verify_refname(rs[i].dst, is_glob);
526
if (st && st != CHECK_REF_FORMAT_ONELEVEL)
527
goto invalid;
528
}
537
if (!*rs[i].src)
538
; /* empty is ok */
539
else if (is_glob) {
521
- st = check_ref_format(rs[i].src);
540
+ st = verify_refname(rs[i].src, is_glob);
541
if (st && st != CHECK_REF_FORMAT_ONELEVEL)
542
goto invalid;
543
}
551
* - otherwise it must be a valid looking ref.
552
*/
553
if (!rs[i].dst) {
535
- st = check_ref_format(rs[i].src);
554
+ st = verify_refname(rs[i].src, is_glob);
555
if (st && st != CHECK_REF_FORMAT_ONELEVEL)
556
goto invalid;
557
} else if (!*rs[i].dst) {
558
goto invalid;
559
} else {
541
- st = check_ref_format(rs[i].dst);
560
+ st = verify_refname(rs[i].dst, is_glob);
561
if (st && st != CHECK_REF_FORMAT_ONELEVEL)
562
goto invalid;
563
}
706
if (!fetch->dst)
707
continue;
708
if (fetch->pattern) {
690
- if (!prefixcmp(needle, key) &&
691
- needle[strlen(key)] == '/') {
709
+ if (!prefixcmp(needle, key)) {
710
*result = xmalloc(strlen(value) +
711
strlen(needle) -
712
strlen(key) + 1);
984
continue;
985
}
986
969
- if (rs[i].pattern &&
970
- !prefixcmp(src->name, rs[i].src) &&
971
- src->name[strlen(rs[i].src)] == '/')
987
+ if (rs[i].pattern && !prefixcmp(src->name, rs[i].src))
988
return rs + i;
989
}
990
if (matching_refs != -1)