diff options
| author | Julian Andres Klode <julian.klode@canonical.com> | 2025-02-24 13:18:08 +0100 |
|---|---|---|
| committer | Julian Andres Klode <jak@debian.org> | 2025-02-24 12:24:17 +0000 |
| commit | 55d3bc60f933faf5f46e31c0522bed8320409dcf (patch) | |
| tree | 798cb5b16edf07bd771f391c83e0dad8da2a044e | |
| parent | fdcdce3bfecd8f7ea577bfa1d1dc7f04e9cf7d45 (diff) | |
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
| -rw-r--r-- | apt-pkg/pkgcachegen.cc | 6 | ||||
| -rw-r--r-- | apt-pkg/pkgcachegen.h | 2 | ||||
| -rwxr-xr-x | 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> VersionExtra{32 * 1024}; + std::vector<VersionExtra> 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 |
