[pacman-dev] [PATCH] do not rely on localdb for hook matching
Andrew Gregory
andrew.gregory.8 at gmail.com
Mon Feb 22 02:46:35 UTC 2016
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 at gmail.com>
---
lib/libalpm/add.c | 14 +++----------
lib/libalpm/hook.c | 4 ++--
lib/libalpm/package.c | 3 +++
lib/libalpm/package.h | 1 +
lib/libalpm/sync.c | 8 ++++++++
test/pacman/tests/TESTS | 1 +
.../tests/hook-pkg-postinstall-trigger-match.py | 23 ++++++++++++++++++++++
7 files changed, 41 insertions(+), 13 deletions(-)
create mode 100644 test/pacman/tests/hook-pkg-postinstall-trigger-match.py
diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c
index 2639fa7..f5c9a95 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 81c347e..6890a6e 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 4f8ddb3..f08df8b 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 65afaf7..9fea356 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 3d3915c..00b68d0 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 acdf769..9c33020 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 0000000..b9b07cd
--- /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")
--
2.7.1
More information about the pacman-dev
mailing list