From c919ad6e4d0de48acb60f2a1371ade9bfb0451f8 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 9 Sep 2012 16:03:52 +0200 Subject: handle packages without a mandatory architecture (debian-policy §5.3) by introducing a pseudo-architecture 'none' so that the small group of users with these packages can get right of them without introducing too much hassle for other users (Closes: #686346) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apt-pkg/pkgcachegen.cc | 53 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) (limited to 'apt-pkg/pkgcachegen.cc') diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index f70cbd02a..490c2ecbb 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -200,7 +200,19 @@ bool pkgCacheGenerator::MergeList(ListParser &List, } if (Arch.empty() == true) - Arch = _config->Find("APT::Architecture"); + { + // use the pseudo arch 'none' for arch-less packages + Arch = "none"; + /* We might built a SingleArchCache here, which we don't want to blow up + just for these :none packages to a proper MultiArchCache, so just ensure + that we have always a native package structure first for SingleArch */ + pkgCache::PkgIterator NP; + if (NewPackage(NP, PackageName, _config->Find("APT::Architecture")) == false) + // TRANSLATOR: The first placeholder is a package name, + // the other two should be copied verbatim as they include debug info + return _error->Error(_("Error occurred while processing %s (%s%d)"), + PackageName.c_str(), "NewPackage", 0); + } // Get a pointer to the package structure pkgCache::PkgIterator Pkg; @@ -418,6 +430,42 @@ bool pkgCacheGenerator::MergeListVersion(ListParser &List, pkgCache::PkgIterator return _error->Error(_("Error occurred while processing %s (%s%d)"), Pkg.Name(), "AddImplicitDepends", 1); } + /* :none packages are packages without an architecture. They are forbidden by + debian-policy, so usually they will only be in (old) dpkg status files - + and dpkg will complain about them - and are pretty rare. We therefore do + usually not create conflicts while the parent is created, but only if a :none + package (= the target) appears. This creates incorrect dependencies on :none + for architecture-specific dependencies on the package we copy from, but we + will ignore this bug as architecture-specific dependencies are only allowed + in jessie and until then the :none packages should be extinct (hopefully). + In other words: This should work long enough to allow graceful removal of + these packages, it is not supposed to allow users to keep using them … */ + if (strcmp(Pkg.Arch(), "none") == 0) + { + pkgCache::PkgIterator M = Grp.FindPreferredPkg(); + if (M.end() == false && Pkg != M) + { + pkgCache::DepIterator D = M.RevDependsList(); + Dynamic DynD(D); + for (; D.end() == false; ++D) + { + if ((D->Type != pkgCache::Dep::Conflicts && + D->Type != pkgCache::Dep::DpkgBreaks && + D->Type != pkgCache::Dep::Replaces) || + D.ParentPkg().Group() == Grp) + continue; + + map_ptrloc *OldDepLast = NULL; + pkgCache::VerIterator ConVersion = D.ParentVer(); + // duplicate the Conflicts/Breaks/Replaces for :none arch + if (D->Version == 0) + NewDepends(Pkg, ConVersion, "", 0, D->Type, OldDepLast); + else + NewDepends(Pkg, ConVersion, D.TargetVer(), + D->CompareOp, D->Type, OldDepLast); + } + } + } } if (unlikely(AddImplicitDepends(Grp, Pkg, Ver) == false)) return _error->Error(_("Error occurred while processing %s (%s%d)"), @@ -871,6 +919,9 @@ bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator &Ver, // Locate the target package pkgCache::PkgIterator Pkg = Grp.FindPkg(Arch); + // we don't create 'none' packages and their dependencies if we can avoid it … + if (Pkg.end() == true && Arch == "none") + return true; Dynamic DynPkg(Pkg); if (Pkg.end() == true) { if (unlikely(Owner->NewPackage(Pkg, PackageName, Arch) == false)) -- cgit v1.2.3-70-g09d2 From 8ec008808cd6083a633685a732dfe9b8a58a89da Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 9 Sep 2012 21:22:54 +0200 Subject: * apt-pkg/pkgcachegen.cc: - do not create 'native' (or now 'none') package structures as a side effect of description translation parsing as it pollutes the cache --- apt-pkg/pkgcachegen.cc | 2 ++ debian/changelog | 3 +++ 2 files changed, 5 insertions(+) (limited to 'apt-pkg/pkgcachegen.cc') diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 490c2ecbb..54b07c465 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -195,8 +195,10 @@ bool pkgCacheGenerator::MergeList(ListParser &List, string const Version = List.Version(); if (Version.empty() == true && Arch.empty() == true) { + // package descriptions if (MergeListGroup(List, PackageName) == false) return false; + continue; } if (Arch.empty() == true) diff --git a/debian/changelog b/debian/changelog index 90f3199b3..936f2557e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -32,6 +32,9 @@ apt (0.9.7.5) UNRELEASED; urgency=low - do not warn about files which have a record in the Release file, but are not present on the CD to mirror the behavior of the other methods and to allow uncompressed indexes to be dropped without scaring users + * apt-pkg/pkgcachegen.cc: + - do not create 'native' (or now 'none') package structures as a side + effect of description translation parsing as it pollutes the cache -- David Kalnischkies Sun, 26 Aug 2012 10:49:17 +0200 -- cgit v1.2.3-70-g09d2 From 7605509f7cc97e5e94d3159f9cd5c2c98b876720 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 19 Sep 2012 11:35:53 +0200 Subject: * apt-pkg/pkgcachegen.cc: - ensure that dependencies for packages:none are always generated --- apt-pkg/pkgcachegen.cc | 2 +- debian/changelog | 8 ++++++++ .../test-bug-686346-package-missing-architecture | 22 ++++++++++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) (limited to 'apt-pkg/pkgcachegen.cc') diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 54b07c465..5f37330c9 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -922,7 +922,7 @@ bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator &Ver, // Locate the target package pkgCache::PkgIterator Pkg = Grp.FindPkg(Arch); // we don't create 'none' packages and their dependencies if we can avoid it … - if (Pkg.end() == true && Arch == "none") + if (Pkg.end() == true && Arch == "none" && strcmp(Ver.ParentPkg().Arch(), "none") != 0) return true; Dynamic DynPkg(Pkg); if (Pkg.end() == true) { diff --git a/debian/changelog b/debian/changelog index 86f8579a7..5b0d049b7 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +apt (0.9.7.6) UNRELEASED; urgency=low + + [ David Kalnischkies ] + * apt-pkg/pkgcachegen.cc: + - ensure that dependencies for packages:none are always generated + + -- David Kalnischkies Wed, 19 Sep 2012 11:29:56 +0200 + apt (0.9.7.5) unstable; urgency=low [ Manpages translation updates ] diff --git a/test/integration/test-bug-686346-package-missing-architecture b/test/integration/test-bug-686346-package-missing-architecture index b0e0aa3c4..b2c9ec9ee 100755 --- a/test/integration/test-bug-686346-package-missing-architecture +++ b/test/integration/test-bug-686346-package-missing-architecture @@ -85,3 +85,25 @@ The following packages have unmet dependencies: pkgg : Conflicts: pkgb but 2 is installed Conflicts: pkgb:none but 1 is installed E: Unmet dependencies. Try using -f." aptget check + +# check that dependencies are generated for none-packages +rm rootdir/var/lib/dpkg/status +insertinstalledpackage 'pkgx' 'none' '1' +insertinstalledpackage 'pkgy' 'none' '1' 'Depends: pkgz, pkgx (>= 1)' +insertinstalledpackage 'pkgz' 'none' '1' +testequal 'Reading package lists... +Building dependency tree... +Reading state information... +The following packages will be REMOVED: + pkgx:none* pkgy:none* +0 upgraded, 0 newly installed, 2 to remove and 0 not upgraded. +Purg pkgy:none [1] +Purg pkgx:none [1]' aptget purge pkgx -s +testequal 'Reading package lists... +Building dependency tree... +Reading state information... +The following packages will be REMOVED: + pkgy:none* pkgz:none* +0 upgraded, 0 newly installed, 2 to remove and 0 not upgraded. +Purg pkgy:none [1] +Purg pkgz:none [1]' aptget purge pkgz -s -- cgit v1.2.3-70-g09d2 From 9abb228384185565478a137446a74e42af0c95b5 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 19 Sep 2012 11:39:20 +0200 Subject: add 3 missing remap registrations causing a segfault in case we use the not remapped iterators after a move of the mmap again --- apt-pkg/pkgcachegen.cc | 3 +++ debian/changelog | 2 ++ 2 files changed, 5 insertions(+) (limited to 'apt-pkg/pkgcachegen.cc') diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 5f37330c9..d5f1f9072 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -209,6 +209,7 @@ bool pkgCacheGenerator::MergeList(ListParser &List, just for these :none packages to a proper MultiArchCache, so just ensure that we have always a native package structure first for SingleArch */ pkgCache::PkgIterator NP; + Dynamic DynPkg(NP); if (NewPackage(NP, PackageName, _config->Find("APT::Architecture")) == false) // TRANSLATOR: The first placeholder is a package name, // the other two should be copied verbatim as they include debug info @@ -459,6 +460,7 @@ bool pkgCacheGenerator::MergeListVersion(ListParser &List, pkgCache::PkgIterator map_ptrloc *OldDepLast = NULL; pkgCache::VerIterator ConVersion = D.ParentVer(); + Dynamic DynV(ConVersion); // duplicate the Conflicts/Breaks/Replaces for :none arch if (D->Version == 0) NewDepends(Pkg, ConVersion, "", 0, D->Type, OldDepLast); @@ -772,6 +774,7 @@ unsigned long pkgCacheGenerator::NewVersion(pkgCache::VerIterator &Ver, // Fill it in Ver = pkgCache::VerIterator(Cache,Cache.VerP + Version); + Dynamic DynV(Ver); Ver->NextVer = Next; Ver->ID = Cache.HeaderP->VersionCount++; map_ptrloc const idxVerStr = WriteStringInMap(VerStr); diff --git a/debian/changelog b/debian/changelog index 5b0d049b7..b7f8e2045 100644 --- a/debian/changelog +++ b/debian/changelog @@ -3,6 +3,8 @@ apt (0.9.7.6) UNRELEASED; urgency=low [ David Kalnischkies ] * apt-pkg/pkgcachegen.cc: - ensure that dependencies for packages:none are always generated + - add 3 missing remap registrations causing a segfault in case + we use the not remapped iterators after a move of the mmap again -- David Kalnischkies Wed, 19 Sep 2012 11:29:56 +0200 -- cgit v1.2.3-70-g09d2 From dfe45e1f1133ffabe55297ae76c77a0767e3ae55 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 13 Oct 2012 09:59:54 +0200 Subject: correct "3 missing" to "2 missing" remap registrations as the Version handled in NewVersion is already registered --- apt-pkg/pkgcachegen.cc | 2 +- debian/changelog | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'apt-pkg/pkgcachegen.cc') diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index d5f1f9072..4eaf40b51 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -774,7 +774,7 @@ unsigned long pkgCacheGenerator::NewVersion(pkgCache::VerIterator &Ver, // Fill it in Ver = pkgCache::VerIterator(Cache,Cache.VerP + Version); - Dynamic DynV(Ver); + //Dynamic DynV(Ver); // caller MergeListVersion already takes care of it Ver->NextVer = Next; Ver->ID = Cache.HeaderP->VersionCount++; map_ptrloc const idxVerStr = WriteStringInMap(VerStr); diff --git a/debian/changelog b/debian/changelog index c06435102..307bd1eee 100644 --- a/debian/changelog +++ b/debian/changelog @@ -6,7 +6,7 @@ apt (0.9.7.6) UNRELEASED; urgency=low [ David Kalnischkies ] * apt-pkg/pkgcachegen.cc: - ensure that dependencies for packages:none are always generated - - add 3 missing remap registrations causing a segfault in case + - add 2 missing remap registrations causing a segfault in case we use the not remapped iterators after a move of the mmap again * apt-pkg/pkgcache.cc: - ignore negative dependencies applying in the same group for -- cgit v1.2.3-70-g09d2 From 7ccb5efb4f5b4471e6b424377f42feff070bb2d3 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 13 Oct 2012 11:16:30 +0200 Subject: write the native architecture as unique string into the cache header as it is used for arch:all packages as a map to arch:native. Otherwise arch comparisons later will see differences (Closes: #689323) --- apt-pkg/pkgcachegen.cc | 4 +++- debian/changelog | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'apt-pkg/pkgcachegen.cc') diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 4eaf40b51..739b538c6 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -69,7 +69,9 @@ pkgCacheGenerator::pkgCacheGenerator(DynamicMMap *pMap,OpProgress *Prog) : *Cache.HeaderP = pkgCache::Header(); map_ptrloc const idxVerSysName = WriteStringInMap(_system->VS->Label); Cache.HeaderP->VerSysName = idxVerSysName; - map_ptrloc const idxArchitecture = WriteStringInMap(_config->Find("APT::Architecture")); + // this pointer is set in ReMap, but we need it now for WriteUniqString + Cache.StringItemP = (pkgCache::StringItem *)Map.Data(); + map_ptrloc const idxArchitecture = WriteUniqString(_config->Find("APT::Architecture")); Cache.HeaderP->Architecture = idxArchitecture; if (unlikely(idxVerSysName == 0 || idxArchitecture == 0)) return; diff --git a/debian/changelog b/debian/changelog index 307bd1eee..c1936a865 100644 --- a/debian/changelog +++ b/debian/changelog @@ -8,6 +8,9 @@ apt (0.9.7.6) UNRELEASED; urgency=low - ensure that dependencies for packages:none are always generated - add 2 missing remap registrations causing a segfault in case we use the not remapped iterators after a move of the mmap again + - write the native architecture as unique string into the cache header + as it is used for arch:all packages as a map to arch:native. + Otherwise arch comparisons later will see differences (Closes: #689323) * apt-pkg/pkgcache.cc: - ignore negative dependencies applying in the same group for M-A:same packages on the real package name as self-conflicts -- cgit v1.2.3-70-g09d2 From 27cae7715489c13c504590cf77a6d22680dbe0b1 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 15 Oct 2012 16:00:44 +0200 Subject: * apt-pkg/pkgcachegen.cc: - Fix crash if the cache is remapped while writing a Provides version (LP: #1066445). --- apt-pkg/pkgcachegen.cc | 8 ++++++-- debian/changelog | 5 +++++ 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'apt-pkg/pkgcachegen.cc') diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 739b538c6..373f6625c 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -975,8 +975,12 @@ bool pkgCacheGenerator::ListParser::NewProvides(pkgCache::VerIterator &Ver, Prv->Version = Ver.Index(); Prv->NextPkgProv = Ver->ProvidesList; Ver->ProvidesList = Prv.Index(); - if (Version.empty() == false && unlikely((Prv->ProvideVersion = WriteString(Version)) == 0)) - return false; + if (Version.empty() == false) { + map_ptrloc const idxProvideVersion = WriteString(Version); + Prv->ProvideVersion = idxProvideVersion; + if (unlikely(idxProvideVersion == 0)) + return false; + } // Locate the target package pkgCache::PkgIterator Pkg; diff --git a/debian/changelog b/debian/changelog index 1fd2e8936..f83d661a7 100644 --- a/debian/changelog +++ b/debian/changelog @@ -33,6 +33,11 @@ apt (0.9.7.6) UNRELEASED; urgency=low * increase the maximum netrc login/password size and show proper error message on overflow + [ Colin Watson ] + * apt-pkg/pkgcachegen.cc: + - Fix crash if the cache is remapped while writing a Provides version + (LP: #1066445). + -- David Kalnischkies Wed, 19 Sep 2012 11:29:56 +0200 apt (0.9.7.5) unstable; urgency=low -- cgit v1.2.3-70-g09d2