aboutsummaryrefslogtreecommitdiffstats
path: root/hook.c
diff options
context:
space:
mode:
Diffstat (limited to 'hook.c')
-rw-r--r--hook.c53
1 files changed, 46 insertions, 7 deletions
diff --git a/hook.c b/hook.c
index f6306d72b3..eebc4d4473 100644
--- a/hook.c
+++ b/hook.c
@@ -7,25 +7,56 @@
#include "run-command.h"
#include "config.h"
#include "strbuf.h"
+#include "environment.h"
+#include "setup.h"
+#include "copy.h"
+
+static int identical_to_template_hook(const char *name, const char *path)
+{
+ const char *env = getenv("GIT_CLONE_TEMPLATE_DIR");
+ const char *template_dir = get_template_dir(env && *env ? env : NULL);
+ struct strbuf template_path = STRBUF_INIT;
+ int found_template_hook, ret;
+
+ strbuf_addf(&template_path, "%s/hooks/%s", template_dir, name);
+ found_template_hook = access(template_path.buf, X_OK) >= 0;
+#ifdef STRIP_EXTENSION
+ if (!found_template_hook) {
+ strbuf_addstr(&template_path, STRIP_EXTENSION);
+ found_template_hook = access(template_path.buf, X_OK) >= 0;
+ }
+#endif
+ if (!found_template_hook)
+ return 0;
+
+ ret = do_files_match(template_path.buf, path);
+
+ strbuf_release(&template_path);
+ return ret;
+}
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)) {
@@ -39,6 +70,14 @@ const char *find_hook(const char *name)
}
return NULL;
}
+ if (!git_hooks_path && git_env_bool("GIT_CLONE_PROTECTION_ACTIVE", 0) &&
+ !identical_to_template_hook(name, path.buf))
+ die(_("active `%s` hook found during `git clone`:\n\t%s\n"
+ "For security reasons, this is disallowed by default.\n"
+ "If this is intentional and the hook should actually "
+ "be run, please\nrun the command again with "
+ "`GIT_CLONE_PROTECTION_ACTIVE=false`"),
+ name, path.buf);
return path.buf;
}