find_hook(): refactor the STRIP_EXTENSION logic

When looking for a hook and not finding one, and when `STRIP_EXTENSION`
is available (read: if we're on Windows and `.exe` is the required
extension for executable programs), we want to look also for a hook with
that extension.

Previously, we added that handling into the conditional block that was
meant to handle when no hook was found (possibly providing some advice
for the user's benefit). If the hook with that file extension was found,
we'd return early from that function instead of writing out said advice,
of course.

However, we're about to introduce a safety valve to prevent hooks from
being run during a clone, to reduce the attack surface of bugs that
allow writing files to be written into arbitrary locations.

To prepare for that, refactor the logic to avoid the early return, by
separating the `STRIP_EXTENSION` handling from the conditional block
handling the case when no hook was found.

This commit is best viewed with `--patience`.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This commit is contained in:
Johannes Schindelin
2024-03-28 19:02:30 +01:00
parent 31572dc420
commit 48c171d927

18
hook.c
View File

@ -7,20 +7,24 @@ const char *find_hook(const char *name)
{
static struct strbuf path = STRBUF_INIT;
int found_hook;
strbuf_reset(&path);
strbuf_git_path(&path, "hooks/%s", name);
if (access(path.buf, X_OK) < 0) {
found_hook = access(path.buf, X_OK) >= 0;
#ifdef STRIP_EXTENSION
if (!found_hook) {
int err = errno;
#ifdef STRIP_EXTENSION
strbuf_addstr(&path, STRIP_EXTENSION);
if (access(path.buf, X_OK) >= 0)
return path.buf;
if (errno == EACCES)
err = errno;
found_hook = access(path.buf, X_OK) >= 0;
if (!found_hook)
errno = err;
}
#endif
if (err == EACCES && advice_enabled(ADVICE_IGNORED_HOOK)) {
if (!found_hook) {
if (errno == EACCES && advice_enabled(ADVICE_IGNORED_HOOK)) {
static struct string_list advise_given = STRING_LIST_INIT_DUP;
if (!string_list_lookup(&advise_given, name)) {