From e8e872c8f93ba13f67b882d64c16606973f0ff67 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Fri, 16 Oct 2015 20:28:26 -0400 Subject: validate hooks after parsing Signed-off-by: Andrew Gregory Signed-off-by: Allan McRae --- lib/libalpm/hook.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/lib/libalpm/hook.c b/lib/libalpm/hook.c index 7c507871..fe4b2041 100644 --- a/lib/libalpm/hook.c +++ b/lib/libalpm/hook.c @@ -79,6 +79,68 @@ static void _alpm_hook_free(struct _alpm_hook_t *hook) } } +static int _alpm_trigger_validate(alpm_handle_t *handle, + struct _alpm_trigger_t *trigger, const char *file) +{ + int ret = 0; + + if(trigger->targets == NULL) { + ret = -1; + _alpm_log(handle, ALPM_LOG_ERROR, + _("Missing trigger targets in hook: %s\n"), file); + } + + if(trigger->type == 0) { + ret = -1; + _alpm_log(handle, ALPM_LOG_ERROR, + _("Missing trigger type in hook: %s\n"), file); + } + + if(trigger->op == 0) { + ret = -1; + _alpm_log(handle, ALPM_LOG_ERROR, + _("Missing trigger operation in hook: %s\n"), file); + } + + return ret; +} + +static int _alpm_hook_validate(alpm_handle_t *handle, + struct _alpm_hook_t *hook, const char *file) +{ + alpm_list_t *i; + int ret = 0; + + if(hook->triggers == NULL) { + /* special case: allow triggerless hooks as a way of creating dummy + * hooks that can be used to mask lower priority hooks */ + return 0; + } + + for(i = hook->triggers; i; i = i->next) { + if(_alpm_trigger_validate(handle, i->data, file) != 0) { + ret = -1; + } + } + + if(hook->cmd == NULL) { + ret = -1; + _alpm_log(handle, ALPM_LOG_ERROR, + _("Missing Exec option in hook: %s\n"), file); + } + + if(hook->when == 0) { + ret = -1; + _alpm_log(handle, ALPM_LOG_ERROR, + _("Missing When option in hook: %s\n"), file); + } else if(hook->when != ALPM_HOOK_PRE_TRANSACTION && hook->abort_on_fail) { + _alpm_log(handle, ALPM_LOG_WARNING, + _("AbortOnFail set for PostTransaction hook: %s\n"), file); + } + + return ret; +} + static int _alpm_hook_parse_cb(const char *file, int line, const char *section, char *key, char *value, void *data) { @@ -395,7 +457,8 @@ int _alpm_hook_run(alpm_handle_t *handle, enum _alpm_hook_when_t when) ret = -1; closedir(d); goto cleanup); _alpm_log(handle, ALPM_LOG_DEBUG, "parsing hook file %s\n", path); - if(parse_ini(path, _alpm_hook_parse_cb, &ctx) != 0) { + if(parse_ini(path, _alpm_hook_parse_cb, &ctx) != 0 + || _alpm_hook_validate(handle, ctx.hook, path)) { _alpm_log(handle, ALPM_LOG_DEBUG, "parsing hook file %s failed\n", path); _alpm_hook_free(ctx.hook); ret = -1; -- cgit v1.2.3-24-g4f1b