summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAndrew Gregory <andrew.gregory.8@gmail.com>2015-10-16 20:28:26 -0400
committerAllan McRae <allan@archlinux.org>2015-10-18 10:59:23 +1000
commite8e872c8f93ba13f67b882d64c16606973f0ff67 (patch)
tree0ef43ff340999681a765aa5d097ebb975b625e0e /lib
parent16718a216ee5607c56d220a198fdb48a923aaafc (diff)
validate hooks after parsing
Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com> Signed-off-by: Allan McRae <allan@archlinux.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/libalpm/hook.c65
1 files changed, 64 insertions, 1 deletions
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;