summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Gregory <andrew.gregory.8@gmail.com>2016-02-21 21:46:35 -0500
committerAllan McRae <allan@archlinux.org>2016-02-23 12:15:43 +1000
commit2ee7a8d89ad693617307260604e1d58757fd2978 (patch)
tree4168d3e07cd4a8ebe21180ac8bc0e27fb05821dd
parentf63854fa96f658ca5bdf2c21a1cd33cf4e3fbdbd (diff)
do not rely on localdb for hook matching
Relying on localdb to determine which trigger operations should match is completely broken for PostTransaction hooks because the localdb has already been updated. Store a copy of the old version of any packages being updated to use instead. Fixes FS#47996 Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com> Signed-off-by: Allan McRae <allan@archlinux.org>
-rw-r--r--lib/libalpm/add.c14
-rw-r--r--lib/libalpm/hook.c4
-rw-r--r--lib/libalpm/package.c3
-rw-r--r--lib/libalpm/package.h1
-rw-r--r--lib/libalpm/sync.c8
-rw-r--r--test/pacman/tests/TESTS1
-rw-r--r--test/pacman/tests/hook-pkg-postinstall-trigger-match.py23
7 files changed, 41 insertions, 13 deletions
diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c
index 2639fa79..f5c9a957 100644
--- a/lib/libalpm/add.c
+++ b/lib/libalpm/add.c
@@ -409,9 +409,8 @@ static int commit_single_pkg(alpm_handle_t *handle, alpm_pkg_t *newpkg,
ASSERT(trans != NULL, return -1);
/* see if this is an upgrade. if so, remove the old package first */
- alpm_pkg_t *local = _alpm_db_get_pkgfromcache(db, newpkg->name);
- if(local) {
- int cmp = _alpm_pkg_compare_versions(newpkg, local);
+ if((oldpkg = newpkg->oldpkg)) {
+ int cmp = _alpm_pkg_compare_versions(newpkg, oldpkg);
if(cmp < 0) {
log_msg = "downgrading";
progress = ALPM_PROGRESS_DOWNGRADE_START;
@@ -427,14 +426,8 @@ static int commit_single_pkg(alpm_handle_t *handle, alpm_pkg_t *newpkg,
}
is_upgrade = 1;
- /* we'll need to save some record for backup checks later */
- if(_alpm_pkg_dup(local, &oldpkg) == -1) {
- ret = -1;
- goto cleanup;
- }
-
/* copy over the install reason */
- newpkg->reason = alpm_pkg_get_reason(local);
+ newpkg->reason = alpm_pkg_get_reason(oldpkg);
} else {
event.operation = ALPM_PACKAGE_INSTALL;
}
@@ -630,7 +623,6 @@ static int commit_single_pkg(alpm_handle_t *handle, alpm_pkg_t *newpkg,
EVENT(handle, &event);
cleanup:
- _alpm_pkg_free(oldpkg);
return ret;
}
diff --git a/lib/libalpm/hook.c b/lib/libalpm/hook.c
index 81c347e1..6890a6ec 100644
--- a/lib/libalpm/hook.c
+++ b/lib/libalpm/hook.c
@@ -374,7 +374,7 @@ static int _alpm_hook_trigger_match_file(alpm_handle_t *handle,
/* check if file will be removed due to package upgrade */
for(i = handle->trans->add; i; i = i->next) {
alpm_pkg_t *spkg = i->data;
- alpm_pkg_t *pkg = alpm_db_get_pkg(handle->db_local, spkg->name);
+ alpm_pkg_t *pkg = spkg->oldpkg;
if(pkg) {
alpm_filelist_t filelist = pkg->files;
size_t f;
@@ -463,7 +463,7 @@ static int _alpm_hook_trigger_match_pkg(alpm_handle_t *handle,
for(i = handle->trans->add; i; i = i->next) {
alpm_pkg_t *pkg = i->data;
if(_alpm_fnmatch_patterns(t->targets, pkg->name) == 0) {
- if(alpm_db_get_pkg(handle->db_local, pkg->name)) {
+ if(pkg->oldpkg) {
if(t->op & ALPM_HOOK_OP_UPGRADE) {
if(hook->needs_targets) {
upgrade = alpm_list_add(upgrade, pkg->name);
diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c
index 4f8ddb3a..f08df8b2 100644
--- a/lib/libalpm/package.c
+++ b/lib/libalpm/package.c
@@ -682,6 +682,7 @@ void _alpm_pkg_free(alpm_pkg_t *pkg)
alpm_list_free(pkg->deltas);
alpm_list_free(pkg->delta_path);
alpm_list_free(pkg->removes);
+ _alpm_pkg_free(pkg->oldpkg);
if(pkg->origin == ALPM_PKG_FROM_FILE) {
FREE(pkg->origin_data.file);
@@ -707,6 +708,8 @@ void _alpm_pkg_free_trans(alpm_pkg_t *pkg)
alpm_list_free(pkg->removes);
pkg->removes = NULL;
+ _alpm_pkg_free(pkg->oldpkg);
+ pkg->oldpkg = NULL;
}
/* Is spkg an upgrade for localpkg? */
diff --git a/lib/libalpm/package.h b/lib/libalpm/package.h
index 65afaf70..9fea3563 100644
--- a/lib/libalpm/package.h
+++ b/lib/libalpm/package.h
@@ -117,6 +117,7 @@ struct __alpm_pkg_t {
alpm_list_t *deltas;
alpm_list_t *delta_path;
alpm_list_t *removes; /* in transaction targets only */
+ alpm_pkg_t *oldpkg; /* in transaction targets only */
struct pkg_operations *ops;
diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c
index 3d3915c3..00b68d05 100644
--- a/lib/libalpm/sync.c
+++ b/lib/libalpm/sync.c
@@ -659,10 +659,15 @@ int _alpm_sync_prepare(alpm_handle_t *handle, alpm_list_t **data)
for(i = trans->add; i; i = i->next) {
/* update download size field */
alpm_pkg_t *spkg = i->data;
+ alpm_pkg_t *lpkg = alpm_db_get_pkg(handle->db_local, spkg->name);
if(compute_download_size(spkg) < 0) {
ret = -1;
goto cleanup;
}
+ if(lpkg && _alpm_pkg_dup(lpkg, &spkg->oldpkg) != 0) {
+ ret = -1;
+ goto cleanup;
+ }
}
cleanup:
@@ -1260,6 +1265,9 @@ static int load_packages(alpm_handle_t *handle, alpm_list_t **data,
pkgfile->reason = spkg->reason;
/* copy over validation method */
pkgfile->validation = spkg->validation;
+ /* transfer oldpkg */
+ pkgfile->oldpkg = spkg->oldpkg;
+ spkg->oldpkg = NULL;
i->data = pkgfile;
/* spkg has been removed from the target list, so we can free the
* sync-specific fields */
diff --git a/test/pacman/tests/TESTS b/test/pacman/tests/TESTS
index acdf769b..9c330203 100644
--- a/test/pacman/tests/TESTS
+++ b/test/pacman/tests/TESTS
@@ -59,6 +59,7 @@ TESTS += test/pacman/tests/hook-file-remove-trigger-match.py
TESTS += test/pacman/tests/hook-file-upgrade-nomatch.py
TESTS += test/pacman/tests/hook-invalid-trigger.py
TESTS += test/pacman/tests/hook-pkg-install-trigger-match.py
+TESTS += test/pacman/tests/hook-pkg-postinstall-trigger-match.py
TESTS += test/pacman/tests/hook-pkg-remove-trigger-match.py
TESTS += test/pacman/tests/hook-pkg-upgrade-trigger-match.py
TESTS += test/pacman/tests/hook-target-list.py
diff --git a/test/pacman/tests/hook-pkg-postinstall-trigger-match.py b/test/pacman/tests/hook-pkg-postinstall-trigger-match.py
new file mode 100644
index 00000000..b9b07cda
--- /dev/null
+++ b/test/pacman/tests/hook-pkg-postinstall-trigger-match.py
@@ -0,0 +1,23 @@
+self.description = "Install a package matching a PostTransaction Install hook"
+
+self.add_script("hook-script", ": > hook-output")
+self.add_hook("hook",
+ """
+ [Trigger]
+ Type = Package
+ Operation = Install
+ Target = foo
+
+ [Action]
+ When = PostTransaction
+ Exec = bin/hook-script
+ """);
+
+sp = pmpkg("foo")
+self.addpkg2db("sync", sp)
+
+self.args = "-S foo"
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=foo")
+self.addrule("FILE_EXIST=hook-output")