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