Junio C Hamano <gitster@xxxxxxxxx> writes: >> I think we've discussed tightening it a few years ago already. >> >> HEAD, MERGE_HEAD, FETCH_HEAD, etc. all are "^[_A-Z]*$" and it may even be >> a good idea to insist "^[_A-Z]*HEAD$" or even "^([A-Z][A-Z]*_)?HEAD$". > > Perhaps like this? Only compile tested... Not quite. There are at least three bugs in the patch. - Some subsystems use random refnames like NOTES_MERGE_PARTIAL that would not match "^([A-Z][A-Z]*_)?HEAD$". The rule needs to be relaxed; - dwim_ref() can be fed "refs/heads/master" and is expected to dwim it to the master branch. - These codepaths get pointer+length so that it can be told to parse only the first 4 bytes in "HEAD:$path". -- >8 -- Subject: [PATCH] Restrict ref-like names immediately below $GIT_DIR We have always dwimmed the user input $string into a ref by first looking directly inside $GIT_DIR, and then in $GIT_DIR/refs, $GIT_DIR/refs/tags, etc., and that is what made git log HEAD..MERGE_HEAD work correctly. This however means that git rev-parse config git log index would look at $GIT_DIR/config and $GIT_DIR/index and see if they are valid refs. To reduce confusion, let's not dwim a path immediately below $GIT_DIR that is not all-caps. Signed-off-by: Junio C Hamano <gitster@xxxxxxxxx> --- sha1_name.c | 23 +++++++++++++++++++++++ 1 files changed, 23 insertions(+), 0 deletions(-) diff --git a/sha1_name.c b/sha1_name.c index 143fd97..5eb19c2 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -261,6 +261,25 @@ static char *substitute_branch_name(const char **string, int *len) return NULL; } +static int ok_at_root_level(const char *str, int len) +{ + int seen_non_root_char = 0; + + while (len--) { + char ch = *str++; + + if (ch == '/') + return 1; + /* + * Only accept likes of .git/HEAD, .git/MERGE_HEAD at + * the root level as a ref. + */ + if (ch != '_' && (ch < 'A' || 'Z' < ch)) + seen_non_root_char = 1; + } + return !seen_non_root_char; +} + int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref) { char *last_branch = substitute_branch_name(&str, &len); @@ -274,6 +293,8 @@ int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref) unsigned char *this_result; int flag; + if (p == ref_rev_parse_rules && !ok_at_root_level(str, len)) + continue; this_result = refs_found ? sha1_from_ref : sha1; mksnpath(fullref, sizeof(fullref), *p, len, str); r = resolve_ref(fullref, this_result, 1, &flag); @@ -302,6 +323,8 @@ int dwim_log(const char *str, int len, unsigned char *sha1, char **log) char path[PATH_MAX]; const char *ref, *it; + if (p == ref_rev_parse_rules && !ok_at_root_level(str, len)) + continue; mksnpath(path, sizeof(path), *p, len, str); ref = resolve_ref(path, hash, 1, NULL); if (!ref) -- 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