From: Michael Haggerty <mhagger@xxxxxxxxxxxx> Implement a new option, REFNAME_RELAXED, which accepts "slightly" illegal refnames--those that might cause confusion with notations like "R1..R2", "^R1", etc. but are unlikely to cause internal errors. Signed-off-by: Michael Haggerty <mhagger@xxxxxxxxxxxx> --- refs.c | 31 +++++++++++++++++++------------ refs.h | 6 +++++- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/refs.c b/refs.c index c4ab64d..3a35e5e 100644 --- a/refs.c +++ b/refs.c @@ -17,14 +17,20 @@ */ /* Return true iff ch is not allowed in reference names. */ -static inline int bad_ref_char(int ch) +static inline int bad_ref_char(int ch, int flags) { - if (((unsigned) ch) <= ' ' || ch == 0x7f || - ch == '~' || ch == '^' || ch == ':' || ch == '\\') - return 1; - /* 2.13 Pattern Matching Notation */ - if (ch == '*' || ch == '?' || ch == '[') /* Unsupported */ - return 1; + if (flags & REFNAME_RELAXED) { + if (ch == '\0' || ch == '\n' || ch == ' ' || + ch == ':' || ch == '\\') + return 1; + } else { + 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; } @@ -46,12 +52,12 @@ static int parse_refname_component(const char *refname, int refnamelen, int flag char ch = refname[i]; if (ch == '/') { break; - } else if (bad_ref_char(ch)) { + } else if (bad_ref_char(ch, flags)) { break; /* Component terminated by illegal character. */ - } else if (last == '.' && ch == '.') { + } else if (!(flags & REFNAME_RELAXED) && last == '.' && ch == '.') { i--; break; /* Component terminated by "..". */ - } else if (last == '@' && ch == '{') { + } else if (!(flags & REFNAME_RELAXED) && last == '@' && ch == '{') { i--; break; /* Refname terminated by "@{". */ } @@ -64,11 +70,12 @@ static int parse_refname_component(const char *refname, int refnamelen, int flag return -1; /* Component starts with '.'. */ /* * Even if leading dots are allowed, don't allow "." - * as a component (".." is treated as a terminator by - * a rule above). + * or ".." as a component. */ if (i == 1) return -1; /* Component equals ".". */ + if (i == 2 && refname[1] == '.') + return -1; /* Component equals "..". */ } if (i >= 5 && !memcmp(&refname[i - 5], ".lock", 5)) return -1; /* Component is not allowed to end with ".lock". */ diff --git a/refs.h b/refs.h index efe13bb..dd6cfe5 100644 --- a/refs.h +++ b/refs.h @@ -115,6 +115,7 @@ extern int for_each_reflog(each_ref_fn, void *); #define REFNAME_REFSPEC_PATTERN 0x02 #define REFNAME_DOT_COMPONENT 0x04 #define REFNAME_FULL 0x08 +#define REFNAME_RELAXED 0x10 /* * Return 0 iff refname has the correct format for a refname according @@ -128,7 +129,10 @@ extern int for_each_reflog(each_ref_fn, void *); * "." or ".."). If REFNAME_FULL is set in flags, then additionally * verify that the refname is a valid full refname--that it either * starts with "refs/" or that it consists of only capital letters and - * underscores (like "HEAD" or "MERGE_HEAD"). + * underscores (like "HEAD" or "MERGE_HEAD"). If REFNAME_RELAXED is + * set in flags, then relax the rules to allow control characters + * except for SP and LF, wildcard characters '?', '*', and '[', ".." + * (but not as a complete refname component), and "@{". */ extern int check_refname_format(const char *refname, int flags); -- 1.7.10 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html