diff options
author | Patrick Steinhardt <ps@pks.im> | 2024-05-07 06:52:51 +0200 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2024-05-07 07:50:48 +0200 |
commit | 0c6bd2b81d1e18dfa1e143c354c554cca34b3685 (patch) | |
tree | d8f8a497b4f516d8a9310190e65a8691ed8586c7 /setup.c | |
parent | path: harden validation of HEAD with non-standard hashes (diff) | |
download | git-0c6bd2b81d1e18dfa1e143c354c554cca34b3685.tar.xz git-0c6bd2b81d1e18dfa1e143c354c554cca34b3685.zip |
path: move `validate_headref()` to its only user
While `validate_headref()` is only called from `is_git_directory()` in
"setup.c", it is currently implemented in "path.c". Move it over such
that it becomes clear that it is only really used during setup in order
to discover repositories.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'setup.c')
-rw-r--r-- | setup.c | 53 |
1 files changed, 53 insertions, 0 deletions
@@ -4,6 +4,7 @@ #include "environment.h" #include "exec-cmd.h" #include "gettext.h" +#include "hex.h" #include "object-name.h" #include "refs.h" #include "repository.h" @@ -341,6 +342,58 @@ int get_common_dir_noenv(struct strbuf *sb, const char *gitdir) return ret; } +static int validate_headref(const char *path) +{ + struct stat st; + char buffer[256]; + const char *refname; + struct object_id oid; + int fd; + ssize_t len; + + if (lstat(path, &st) < 0) + return -1; + + /* Make sure it is a "refs/.." symlink */ + if (S_ISLNK(st.st_mode)) { + len = readlink(path, buffer, sizeof(buffer)-1); + if (len >= 5 && !memcmp("refs/", buffer, 5)) + return 0; + return -1; + } + + /* + * Anything else, just open it and try to see if it is a symbolic ref. + */ + fd = open(path, O_RDONLY); + if (fd < 0) + return -1; + len = read_in_full(fd, buffer, sizeof(buffer)-1); + close(fd); + + if (len < 0) + return -1; + buffer[len] = '\0'; + + /* + * Is it a symbolic ref? + */ + if (skip_prefix(buffer, "ref:", &refname)) { + while (isspace(*refname)) + refname++; + if (starts_with(refname, "refs/")) + return 0; + } + + /* + * Is this a detached HEAD? + */ + if (get_oid_hex_any(buffer, &oid) != GIT_HASH_UNKNOWN) + return 0; + + return -1; +} + /* * Test if it looks like we're at a git directory. * We want to see: |