File paths are resolved if necessary during inter-package conflict checks so that packages carrying the same effective file due to directory symlinks on the filesystem are flagged as conflicting. Signed-off-by: Allan McRae <allan@archlinux.org> --- lib/libalpm/conflict.c | 5 +++++ lib/libalpm/filelist.c | 13 +++++-------- test/pacman/tests/fileconflict001.py | 2 -- test/pacman/tests/fileconflict016.py | 2 -- test/pacman/tests/fileconflict017.py | 26 ++++++++++++++++++++++++++ 5 files changed, 36 insertions(+), 12 deletions(-) create mode 100644 test/pacman/tests/fileconflict017.py diff --git a/lib/libalpm/conflict.c b/lib/libalpm/conflict.c index ccfe990..afef56c 100644 --- a/lib/libalpm/conflict.c +++ b/lib/libalpm/conflict.c @@ -361,12 +361,17 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, int percent = (current * 100) / numtargs; PROGRESS(handle, ALPM_PROGRESS_CONFLICTS_START, "", percent, numtargs, current); + + _alpm_filelist_resolve(handle, alpm_pkg_get_files(p1)); + /* CHECK 1: check every target against every target */ _alpm_log(handle, ALPM_LOG_DEBUG, "searching for file conflicts: %s\n", p1->name); for(j = i->next; j; j = j->next) { alpm_list_t *common_files; alpm_pkg_t *p2 = j->data; + _alpm_filelist_resolve(handle, alpm_pkg_get_files(p2)); + common_files = _alpm_filelist_intersection(alpm_pkg_get_files(p1), alpm_pkg_get_files(p2)); diff --git a/lib/libalpm/filelist.c b/lib/libalpm/filelist.c index 288907a..59bf1ec 100644 --- a/lib/libalpm/filelist.c +++ b/lib/libalpm/filelist.c @@ -241,21 +241,18 @@ alpm_list_t *_alpm_filelist_intersection(alpm_filelist_t *filesA, int cmp, isdirA, isdirB; char *strA, *strB; - alpm_file_t *fileA = filesA->files + ctrA; - alpm_file_t *fileB = filesB->files + ctrB; - isdirA = 0; - strA = fileA->name; + strA = filesA->resolved_path[ctrA]; if(strA[strlen(strA)-1] == '/') { isdirA = 1; - strA = strndup(fileA->name, strlen(strA)-1); + strA = strndup(filesA->resolved_path[ctrA], strlen(strA)-1); } isdirB = 0; - strB = fileB->name; + strB = filesB->resolved_path[ctrB]; if(strB[strlen(strB)-1] == '/') { isdirB = 1; - strB = strndup(fileB->name, strlen(strB)-1); + strB = strndup(filesB->resolved_path[ctrB], strlen(strB)-1); } cmp = strcmp(strA, strB); @@ -273,7 +270,7 @@ alpm_list_t *_alpm_filelist_intersection(alpm_filelist_t *filesA, /* when not directories, item in both qualifies as an intersect */ if(! (isdirA && isdirB)) { - ret = alpm_list_add(ret, fileA); + ret = alpm_list_add(ret, filesA->files + ctrA); } ctrA++; ctrB++; diff --git a/test/pacman/tests/fileconflict001.py b/test/pacman/tests/fileconflict001.py index e1371f8..b1ad5e1 100644 --- a/test/pacman/tests/fileconflict001.py +++ b/test/pacman/tests/fileconflict001.py @@ -25,5 +25,3 @@ self.addrule("!PKG_EXIST=pkg2") self.addrule("FILE_EXIST=dir/realdir/realfile") self.addrule("!FILE_EXIST=dir/realdir/file") - -self.expectfailure = True diff --git a/test/pacman/tests/fileconflict016.py b/test/pacman/tests/fileconflict016.py index 5625984..c5daf48 100644 --- a/test/pacman/tests/fileconflict016.py +++ b/test/pacman/tests/fileconflict016.py @@ -22,5 +22,3 @@ self.addrule("PACMAN_RETCODE=1") self.addrule("!PKG_EXIST=pkg1") self.addrule("!PKG_EXIST=pkg2") - -self.expectfailure = True diff --git a/test/pacman/tests/fileconflict017.py b/test/pacman/tests/fileconflict017.py new file mode 100644 index 0000000..3855a93 --- /dev/null +++ b/test/pacman/tests/fileconflict017.py @@ -0,0 +1,26 @@ +self.description = "file conflict with same effective path across packages (directory symlink - deep)" + +lp1 = pmpkg("filesystem", "1.0-1") +lp1.files = ["usr/", + "usr/lib/", + "lib -> usr/lib/"] +self.addpkg2db("local", lp1) + +p1 = pmpkg("pkg1") +p1.files = ["lib/", + "lib/foo/", + "lib/foo/bar"] +self.addpkg2db("sync", p1) + +p2 = pmpkg("pkg2") +p2.files = ["usr/", + "usr/lib/", + "usr/lib/foo/", + "usr/lib/foo/bar"] +self.addpkg2db("sync", p2) + +self.args = "-S pkg1 pkg2" + +self.addrule("PACMAN_RETCODE=1") +self.addrule("!PKG_EXIST=pkg1") +self.addrule("!PKG_EXIST=pkg2") -- 1.7.11.3