@@ -19,12 +19,14 @@ struct ref_lock {
1919 * 1: End-of-component
2020 * 2: ., look for a preceding . to reject .. in refs
2121 * 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
2325 */
2426static unsigned char refname_disposition [256 ] = {
2527 1 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 ,
2628 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 ,
2830 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 4 , 0 , 0 , 0 , 0 , 4 ,
2931 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
3032 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] = {
7577 *
7678 * - any path component of it begins with ".", or
7779 * - 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
8286 */
83- static int check_refname_component (const char * refname , int flags )
87+ static int check_refname_component (const char * refname , int * flags )
8488{
8589 const char * cp ;
8690 char last = '\0' ;
@@ -101,6 +105,16 @@ static int check_refname_component(const char *refname, int flags)
101105 break ;
102106 case 4 :
103107 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 ;
104118 }
105119 last = ch ;
106120 }
@@ -125,18 +139,10 @@ int check_refname_format(const char *refname, int flags)
125139
126140 while (1 ) {
127141 /* 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+
140146 component_count ++ ;
141147 if (refname [component_len ] == '\0' )
142148 break ;
0 commit comments