[pacman-dev] [PATCH] Fix "-Sd conflict_pkg" bug

Nagy Gabor ngaba at bibl.u-szeged.hu
Sat Sep 12 16:01:05 EDT 2009


If the -d switch was invoked with -S (or -U), the removes list was simply
lost, because trans->remove was computed in an
"if(!(trans->flags & PM_TRANS_FLAG_NODEPS))" block.

I've added a new pactest file, sync045.py (derived from sync043.py) to test
this.

Additionally, I did some other minor cleanups in sync_prepare:
 * preferred list is not needed anymore
 * I removed a needless alpm_list_remove_dupes line (the target list should
   not contain dupes at all)
 * I moved alpm_list_free(remove); to cleanup part to eliminate a possible
   memleak

Signed-off-by: Nagy Gabor <ngaba at bibl.u-szeged.hu>
---
 lib/libalpm/sync.c       |   25 ++++++++++---------------
 pactest/tests/sync045.py |   18 ++++++++++++++++++
 2 files changed, 28 insertions(+), 15 deletions(-)
 create mode 100644 pactest/tests/sync045.py

diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c
index d676778..91da313 100644
--- a/lib/libalpm/sync.c
+++ b/lib/libalpm/sync.c
@@ -328,7 +328,6 @@ static int compute_download_size(pmpkg_t *newpkg)
 int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync, alpm_list_t **data)
 {
 	alpm_list_t *deps = NULL;
-	alpm_list_t *preferred = NULL;
 	alpm_list_t *unresolvable = NULL;
 	alpm_list_t *i, *j;
 	alpm_list_t *remove = NULL;
@@ -351,32 +350,29 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
 		EVENT(trans, PM_TRANS_EVT_RESOLVEDEPS_START, NULL, NULL);
 		_alpm_log(PM_LOG_DEBUG, "resolving target's dependencies\n");
 
-		/* build remove list and preferred list for resolvedeps */
+		/* build remove list for resolvedeps */
 		for(i = trans->add; i; i = i->next) {
 			pmpkg_t *spkg = i->data;
 			for(j = spkg->removes; j; j = j->next) {
 				remove = alpm_list_add(remove, j->data);
 			}
-			preferred = alpm_list_add(preferred, spkg);
 		}
 
 		/* Resolve packages in the transaction one at a time, in addtion
 		   building up a list of packages which could not be resolved. */
 		for(i = trans->add; i; i = i->next) {
 			pmpkg_t *pkg = i->data;
-			if(_alpm_resolvedeps(db_local, dbs_sync, pkg, preferred,
+			if(_alpm_resolvedeps(db_local, dbs_sync, pkg, trans->add,
 						&resolved, remove, data) == -1) {
 				unresolvable = alpm_list_add(unresolvable, pkg);
 			}
 			/* Else, [resolved] now additionally contains [pkg] and all of its
 			   dependencies not already on the list */
 		}
-		alpm_list_free(preferred);
 
 		/* If there were unresolvable top-level packages, prompt the user to
 		   see if they'd like to ignore them rather than failing the sync */
 		if(unresolvable != NULL) {
-			unresolvable = alpm_list_remove_dupes(unresolvable);
 			int remove_unresolvable = 0;
 			QUESTION(handle->trans, PM_TRANS_CONV_REMOVE_PKGS, unresolvable,
 					NULL, NULL, &remove_unresolvable);
@@ -536,17 +532,15 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
 		alpm_list_free(deps);
 	}
 
-	if(!(trans->flags & PM_TRANS_FLAG_NODEPS)) {
-		/* rebuild remove list */
-		alpm_list_free(remove);
-		trans->remove = NULL;
-		for(i = trans->add; i; i = i->next) {
-			pmpkg_t *spkg = i->data;
-			for(j = spkg->removes; j; j = j->next) {
-				trans->remove = alpm_list_add(trans->remove, _alpm_pkg_dup(j->data));
-			}
+	/* Build trans->remove list */
+	for(i = trans->add; i; i = i->next) {
+		pmpkg_t *spkg = i->data;
+		for(j = spkg->removes; j; j = j->next) {
+			trans->remove = alpm_list_add(trans->remove, _alpm_pkg_dup(j->data));
 		}
+	}
 
+	if(!(trans->flags & PM_TRANS_FLAG_NODEPS)) {
 		_alpm_log(PM_LOG_DEBUG, "checking dependencies\n");
 		deps = alpm_checkdeps(_alpm_db_get_pkgcache(db_local), 1, trans->remove, trans->add);
 		if(deps) {
@@ -572,6 +566,7 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
 
 cleanup:
 	alpm_list_free(unresolvable);
+	alpm_list_free(remove);
 
 	return(ret);
 }
diff --git a/pactest/tests/sync045.py b/pactest/tests/sync045.py
new file mode 100644
index 0000000..574c0a5
--- /dev/null
+++ b/pactest/tests/sync045.py
@@ -0,0 +1,18 @@
+self.description = "Install a sync package conflicting with two local ones (-d)"
+
+sp = pmpkg("pkg1")
+sp.conflicts = ["pkg2", "pkg3"]
+self.addpkg2db("sync", sp);
+
+lp1 = pmpkg("pkg2")
+self.addpkg2db("local", lp1);
+
+lp2 = pmpkg("pkg3")
+self.addpkg2db("local", lp2);
+
+self.args = "-Sd %s --ask=4" % sp.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("!PKG_EXIST=pkg2")
+self.addrule("!PKG_EXIST=pkg3")
-- 
1.6.4.2



More information about the pacman-dev mailing list