diff options
author | Junio C Hamano <gitster@pobox.com> | 2024-05-30 23:15:10 +0200 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2024-05-30 23:15:11 +0200 |
commit | a60c21b7206fff1a6ab561e29ac7312c437d2592 (patch) | |
tree | 0539b0fce049505d99d73b986ed7c459c54ba1e6 /setup.c | |
parent | The eighth batch (diff) | |
parent | repository: stop setting SHA1 as the default object hash (diff) | |
download | git-a60c21b7206fff1a6ab561e29ac7312c437d2592.tar.xz git-a60c21b7206fff1a6ab561e29ac7312c437d2592.zip |
Merge branch 'ps/undecided-is-not-necessarily-sha1'
Before discovering the repository details, We used to assume SHA-1
as the "default" hash function, which has been corrected. Hopefully
this will smoke out codepaths that rely on such an unwarranted
assumptions.
* ps/undecided-is-not-necessarily-sha1:
repository: stop setting SHA1 as the default object hash
oss-fuzz/commit-graph: set up hash algorithm
builtin/shortlog: don't set up revisions without repo
builtin/diff: explicitly set hash algo when there is no repo
builtin/bundle: abort "verify" early when there is no repository
builtin/blame: don't access potentially unitialized `the_hash_algo`
builtin/rev-parse: allow shortening to more than 40 hex characters
remote-curl: fix parsing of detached SHA256 heads
attr: fix BUG() when parsing attrs outside of repo
attr: don't recompute default attribute source
parse-options-cb: only abbreviate hashes when hash algo is known
path: move `validate_headref()` to its only user
path: harden validation of HEAD with non-standard hashes
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" @@ -342,6 +343,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: |