From: David Turner <dturner@xxxxxxxxxxxxxxxx> This function does not contain any backend specific code, so move it to the common code. This function might be used by other refs backends. While we are doing so, improve the comment's grammar and clarify a safety rule. Signed-off-by: Ronnie Sahlberg <sahlberg@xxxxxxxxxx> Signed-off-by: David Turner <dturner@xxxxxxxxxxxxxxxx> Signed-off-by: Junio C Hamano <gitster@xxxxxxxxx> Signed-off-by: Michael Haggerty <mhagger@xxxxxxxxxxxx> --- refs/files-backend.c | 33 --------------------------------- refs/refs-internal.h | 15 +++++++++++++++ refs/refs.c | 24 ++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 33 deletions(-) diff --git a/refs/files-backend.c b/refs/files-backend.c index 1719720..3a4aff6 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -196,39 +196,6 @@ static struct ref_dir *get_ref_dir(struct ref_entry *entry) return dir; } -/* - * Check if a refname is safe. - * For refs that start with "refs/" we consider it safe as long they do - * not try to resolve to outside of refs/. - * - * For all other refs we only consider them safe iff they only contain - * upper case characters and '_' (like "HEAD" AND "MERGE_HEAD", and not like - * "config"). - */ -static int refname_is_safe(const char *refname) -{ - if (starts_with(refname, "refs/")) { - char *buf; - int result; - - buf = xmalloc(strlen(refname) + 1); - /* - * Does the refname try to escape refs/? - * For example: refs/foo/../bar is safe but refs/foo/../../bar - * is not. - */ - result = !normalize_path_copy(buf, refname + strlen("refs/")); - free(buf); - return result; - } - while (*refname) { - if (!isupper(*refname) && *refname != '_') - return 0; - refname++; - } - return 1; -} - static struct ref_entry *create_ref_entry(const char *refname, const unsigned char *sha1, int flag, int check_name) diff --git a/refs/refs-internal.h b/refs/refs-internal.h index 94f5dde..5ae084b 100644 --- a/refs/refs-internal.h +++ b/refs/refs-internal.h @@ -10,6 +10,21 @@ #include "../refs.h" /* + * Return true iff refname is minimally safe. "Safe" here means that + * deleting a loose reference by this name will not do any damage, for + * example by causing a file that is not a reference to be deleted. + * This function does not check that the reference name is legal; for + * that, use check_refname_format(). + * + * We consider a refname that starts with "refs/" to be safe as long + * as any ".." components that it might contain do not escape "refs/". + * Names that do not start with "refs/" are considered safe iff they + * consist entirely of upper case characters and '_' (like "HEAD" and + * "MERGE_HEAD" but not "config" or "FOO/BAR"). + */ +int refname_is_safe(const char *refname); + +/* * Flag passed to lock_ref_sha1_basic() telling it to tolerate broken * refs (i.e., because the reference is about to be deleted anyway). */ diff --git a/refs/refs.c b/refs/refs.c index 0d0579f..31f1b19 100644 --- a/refs/refs.c +++ b/refs/refs.c @@ -949,3 +949,27 @@ int ref_transaction_verify(struct ref_transaction *transaction, NULL, old_sha1, flags, NULL, err); } + +int refname_is_safe(const char *refname) +{ + if (starts_with(refname, "refs/")) { + char *buf; + int result; + + buf = xmalloc(strlen(refname) + 1); + /* + * Does the refname try to escape refs/? + * For example: refs/foo/../bar is safe but refs/foo/../../bar + * is not. + */ + result = !normalize_path_copy(buf, refname + strlen("refs/")); + free(buf); + return result; + } + while (*refname) { + if (!isupper(*refname) && *refname != '_') + return 0; + refname++; + } + return 1; +} -- 2.6.2 -- 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