|
|
|
@ -6,8 +6,29 @@
@@ -6,8 +6,29 @@
|
|
|
|
|
#include "string-list.h" |
|
|
|
|
|
|
|
|
|
/* |
|
|
|
|
* Make sure "ref" is something reasonable to have under ".git/refs/"; |
|
|
|
|
* We do not like it if: |
|
|
|
|
* How to handle various characters in refnames: |
|
|
|
|
* 0: An acceptable character for refs |
|
|
|
|
* 1: End-of-component |
|
|
|
|
* 2: ., look for a preceding . to reject .. in refs |
|
|
|
|
* 3: {, look for a preceding @ to reject @{ in refs |
|
|
|
|
* 4: A bad character: ASCII control characters, "~", "^", ":" or SP |
|
|
|
|
*/ |
|
|
|
|
static unsigned char refname_disposition[256] = { |
|
|
|
|
1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, |
|
|
|
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, |
|
|
|
|
4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 1, |
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 4, |
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 4, 0, |
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 4, 4 |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/* |
|
|
|
|
* Try to read one refname component from the front of refname. |
|
|
|
|
* Return the length of the component found, or -1 if the component is |
|
|
|
|
* not legal. It is legal if it is something reasonable to have under |
|
|
|
|
* ".git/refs/"; We do not like it if: |
|
|
|
|
* |
|
|
|
|
* - any path component of it begins with ".", or |
|
|
|
|
* - it has double dots "..", or |
|
|
|
@ -16,41 +37,31 @@
@@ -16,41 +37,31 @@
|
|
|
|
|
* - it ends with ".lock" |
|
|
|
|
* - it contains a "\" (backslash) |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
/* Return true iff ch is not allowed in reference names. */ |
|
|
|
|
static inline int bad_ref_char(int ch) |
|
|
|
|
{ |
|
|
|
|
if (((unsigned) ch) <= ' ' || ch == 0x7f || |
|
|
|
|
ch == '~' || ch == '^' || ch == ':' || ch == '\\') |
|
|
|
|
return 1; |
|
|
|
|
/* 2.13 Pattern Matching Notation */ |
|
|
|
|
if (ch == '*' || ch == '?' || ch == '[') /* Unsupported */ |
|
|
|
|
return 1; |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* |
|
|
|
|
* Try to read one refname component from the front of refname. Return |
|
|
|
|
* the length of the component found, or -1 if the component is not |
|
|
|
|
* legal. |
|
|
|
|
*/ |
|
|
|
|
static int check_refname_component(const char *refname, int flags) |
|
|
|
|
{ |
|
|
|
|
const char *cp; |
|
|
|
|
char last = '\0'; |
|
|
|
|
|
|
|
|
|
for (cp = refname; ; cp++) { |
|
|
|
|
char ch = *cp; |
|
|
|
|
if (ch == '\0' || ch == '/') |
|
|
|
|
int ch = *cp & 255; |
|
|
|
|
unsigned char disp = refname_disposition[ch]; |
|
|
|
|
switch (disp) { |
|
|
|
|
case 1: |
|
|
|
|
goto out; |
|
|
|
|
case 2: |
|
|
|
|
if (last == '.') |
|
|
|
|
return -1; /* Refname contains "..". */ |
|
|
|
|
break; |
|
|
|
|
case 3: |
|
|
|
|
if (last == '@') |
|
|
|
|
return -1; /* Refname contains "@{". */ |
|
|
|
|
break; |
|
|
|
|
if (bad_ref_char(ch)) |
|
|
|
|
return -1; /* Illegal character in refname. */ |
|
|
|
|
if (last == '.' && ch == '.') |
|
|
|
|
return -1; /* Refname contains "..". */ |
|
|
|
|
if (last == '@' && ch == '{') |
|
|
|
|
return -1; /* Refname contains "@{". */ |
|
|
|
|
case 4: |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
last = ch; |
|
|
|
|
} |
|
|
|
|
out: |
|
|
|
|
if (cp == refname) |
|
|
|
|
return 0; /* Component has zero length. */ |
|
|
|
|
if (refname[0] == '.') { |
|
|
|
|