21
* 2: ., look for a preceding . to reject .. in refs
22
* 3: {, look for a preceding @ to reject @{ in refs
23
* 4: A bad character: ASCII control characters, and
24
- * "*", ":", "?", "[", "\", "^", "~", SP, or TAB
24
+ * ":", "?", "[", "\", "^", "~", SP, or TAB
25
+ * 5: *, reject unless REFNAME_REFSPEC_PATTERN is set
26
*/
27
static unsigned char refname_disposition[256] = {
28
1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
29
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
29
- 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 1,
30
+ 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 2, 1,
31
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 4,
32
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
33
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 4, 0,
74
* - any path component of it begins with ".", or
75
* - it has double dots "..", or
76
* - it has ASCII control characters, or
76
- * - it has "*", ":", "?", "[", "\", "^", "~", SP, or TAB anywhere, or
77
+ * - it has ":", "?", "[", "\", "^", "~", SP, or TAB anywhere, or
78
+ * - it has "*" anywhere unless REFNAME_REFSPEC_PATTERN is set, or
79
* - it ends with a "/", or
80
* - it ends with ".lock", or
81
* - it contains a "@{" portion
82
*/
81
-static int check_refname_component(const char *refname, int flags)
83
+static int check_refname_component(const char *refname, int *flags)
84
{
85
const char *cp;
86
char last = '\0';
101
break;
102
case 4:
103
return -1;
104
+ case 5:
105
+ if (!(*flags & REFNAME_REFSPEC_PATTERN))
106
+ return -1; /* refspec can't be a pattern */
107
+
108
+ /*
109
+ * Unset the pattern flag so that we only accept
110
+ * a single asterisk for one side of refspec.
111
+ */
112
+ *flags &= ~ REFNAME_REFSPEC_PATTERN;
113
+ break;
114
}
115
last = ch;
116
}
135
136
while (1) {
137
/* We are at the start of a path component. */
126
- component_len = check_refname_component(refname, flags);
127
- if (component_len <= 0) {
128
- if ((flags & REFNAME_REFSPEC_PATTERN) &&
129
- refname[0] == '*' &&
130
- (refname[1] == '\0' || refname[1] == '/')) {
131
- /* Accept one wildcard as a full refname component. */
132
- flags &= ~REFNAME_REFSPEC_PATTERN;
133
- component_len = 1;
134
- } else {
135
- return -1;
136
- }
137
- }
138
+ component_len = check_refname_component(refname, &flags);
139
+ if (component_len <= 0)
140
+ return -1;
141
+
142
component_count++;
143
if (refname[component_len] == '\0')
144
break;