summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Andres Klode <jak@debian.org>2017-01-25 03:38:59 +0100
committerJulian Andres Klode <jak@debian.org>2017-01-28 14:06:29 +0100
commit7b78e8bef1fc9de22d826db1db9df25f97d3710c (patch)
tree3d0fb96a6bac9e27ed2ccf2c552bea6a970f4709
parent84285d17bab32a0ceafe31a5b2be61cc4f520b42 (diff)
Only merge acquire items with the same meta key
Since the introduction of by-hash, two differently named files might have the same real URL. In our case, the files icons-64x64.tar.gz and icons-128x128.tar.gz of empty tarballs. APT would try to merge them and end with weird errors because it completed the first download and enters the second stage for decompressing and verifying. After that it would queue a new item to copy the original file to the location, but that copy item would be in the wrong stage, causing it to use the hashes for the decompressed item. Closes: #838441
-rw-r--r--apt-pkg/acquire.cc18
1 files changed, 17 insertions, 1 deletions
diff --git a/apt-pkg/acquire.cc b/apt-pkg/acquire.cc
index 5c195786b..b62c50c00 100644
--- a/apt-pkg/acquire.cc
+++ b/apt-pkg/acquire.cc
@@ -900,11 +900,27 @@ pkgAcquire::Queue::~Queue()
/* */
bool pkgAcquire::Queue::Enqueue(ItemDesc &Item)
{
+ // MetaKeysMatch checks whether the two items have no non-matching
+ // meta-keys. If the items are not transaction items, it returns
+ // true, so other items can still be merged.
+ auto MetaKeysMatch = [](pkgAcquire::ItemDesc const &A, pkgAcquire::Queue::QItem const *B) {
+ auto OwnerA = dynamic_cast<pkgAcqTransactionItem*>(A.Owner);
+ if (OwnerA == nullptr)
+ return true;
+
+ for (auto const & OwnerBUncast : B->Owners) {
+ auto OwnerB = dynamic_cast<pkgAcqTransactionItem*>(OwnerBUncast);
+
+ if (OwnerB != nullptr && OwnerA->GetMetaKey() != OwnerB->GetMetaKey())
+ return false;
+ }
+ return true;
+ };
QItem **OptimalI = &Items;
QItem **I = &Items;
// move to the end of the queue and check for duplicates here
for (; *I != 0; ) {
- if (Item.URI == (*I)->URI)
+ if (Item.URI == (*I)->URI && MetaKeysMatch(Item, *I))
{
if (_config->FindB("Debug::pkgAcquire::Worker",false) == true)
std::cerr << " @ Queue: Action combined for " << Item.URI << " and " << (*I)->URI << std::endl;