From 55d3bc60f933faf5f46e31c0522bed8320409dcf Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Mon, 24 Feb 2025 13:18:08 +0100 Subject: Fix crash in VersionExtra using --with-source etc VersionExtra holds, at runtime, the SHA256 of the packages being added to try to avoid deduplicating obviously different packages; the SHA256 itself is too large to store in the cache. When volatile sources are used, the VersionExtra array is not initialized, or rather it used to be initialized to 32*1024 zero elements as a performance optimization. This meant that specifying --with-source with a package that looks like a duplicate of a version with an ID >= 32*1024 triggered the assertion; so we could not reproduce it easily in the test suite. Remove the optimized initialization to make the behavior more uniform; and treat too large version IDs as having no SHA256. Closes: #1098702 --- apt-pkg/pkgcachegen.cc | 6 ++++-- apt-pkg/pkgcachegen.h | 2 +- test/integration/test-same-version-but-different | 10 ++++++++++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 6e115e4f4..7d93db4b4 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -68,6 +68,8 @@ pkgCacheGenerator::pkgCacheGenerator(DynamicMMap *pMap,OpProgress *Prog) : Map(*pMap), Cache(pMap,false), Progress(Prog), CurrentRlsFile(nullptr), CurrentFile(nullptr), d(nullptr) { + // Reserve some space for version extra data, to avoid lots of small resizes. + VersionExtra.reserve(32 * 1024); } bool pkgCacheGenerator::Start() { @@ -396,8 +398,8 @@ bool pkgCacheGenerator::MergeListVersion(ListParser &List, pkgCache::PkgIterator if (List.SameVersion(Hash, Ver)) { // We do not have SHA256 for both, so we cannot compare them, trust the call from SameVersion() - if (ListSHA256.empty() || VersionExtra[Ver->ID].SHA256[0] == 0) - break; + if (ListSHA256.empty() || Ver->ID >= VersionExtra.size() || VersionExtra[Ver->ID].SHA256[0] == 0) + break; // We have SHA256 for both, so they must match. if (ListSHA256 == std::string_view(VersionExtra[Ver->ID].SHA256, 64)) break; diff --git a/apt-pkg/pkgcachegen.h b/apt-pkg/pkgcachegen.h index 85c80035a..b67b37559 100644 --- a/apt-pkg/pkgcachegen.h +++ b/apt-pkg/pkgcachegen.h @@ -80,7 +80,7 @@ class APT_HIDDEN pkgCacheGenerator /*{{{*/ { char SHA256[64]; }; - std::vector VersionExtra{32 * 1024}; + std::vector VersionExtra; friend class pkgCacheListParser; typedef pkgCacheListParser ListParser; diff --git a/test/integration/test-same-version-but-different b/test/integration/test-same-version-but-different index 595a66fb6..e57150cd6 100755 --- a/test/integration/test-same-version-but-different +++ b/test/integration/test-same-version-but-different @@ -107,3 +107,13 @@ testsuccessequal "diff-sha256: 500 file:${APTARCHIVE} testing/main all Packages 1 500 500 file:${APTARCHIVE} unstable/main all Packages" apt policy diff-sha256 +testsuccessequal "diff-sha256: + Installed: (none) + Candidate: 1 + Version table: + 1 500 + 500 file:${APTARCHIVE} testing/main all Packages + 500 ${APTARCHIVE}/dists/unstable/main/binary-all/Packages + 500 ${APTARCHIVE}/dists/testing/main/binary-all/Packages + 1 500 + 500 file:${APTARCHIVE} unstable/main all Packages" apt policy diff-sha256 --with-source ${APTARCHIVE}/dists/unstable/main/binary-all/Packages --with-source ${APTARCHIVE}/dists/testing/main/binary-all/Packages -- cgit v1.2.3-70-g09d2