From c9db1f6b806af175b57e8db5bf192de2ff9e0beb Mon Sep 17 00:00:00 2001
From: Julian Andres Klode <julian.klode@canonical.com>
Date: Wed, 21 Mar 2018 11:49:03 +0100
Subject: [PATCH] aptcc: Not all downloads have to be packages

When the mirror method is used in apt 1.6 or newer, a mirror list is
downloaded prior to any package, causing PackageKit to crash after
casting its item to pkgAcqArchiveSane.

pkgAcqArchiveSane is a local workaround to expose some protected
stuff in pkgAcqArchive, so we first do a dynamic_cast to pkgAcqArchive
which will be nullptr if it is not a pkgAcqArchive and then cast it
statically to pkgAcqArchiveSane.

Bug-Ubuntu: https://launchpad.net/bugs/1754265
---
 backends/aptcc/acqpkitstatus.cpp |  5 ++++-
 backends/aptcc/apt-intf.cpp      | 10 ++++++++--
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/backends/aptcc/acqpkitstatus.cpp b/backends/aptcc/acqpkitstatus.cpp
index 23314c255..6d30f58f2 100644
--- a/backends/aptcc/acqpkitstatus.cpp
+++ b/backends/aptcc/acqpkitstatus.cpp
@@ -198,7 +198,10 @@ void AcqPackageKitStatus::updateStatus(pkgAcquire::ItemDesc & Itm, int status)
 
     // The pkgAcquire::Item had a version hiden on it's subclass
     // pkgAcqArchive but it was protected our subclass exposes that
-    pkgAcqArchiveSane *archive = static_cast<pkgAcqArchiveSane*>(Itm.Owner);
+    pkgAcqArchiveSane *archive = static_cast<pkgAcqArchiveSane*>(dynamic_cast<pkgAcqArchive*>(Itm.Owner));
+    if (archive == nullptr) {
+        return;
+    }
     const pkgCache::VerIterator ver = archive->version();
     if (ver.end() == true) {
         return;
diff --git a/backends/aptcc/apt-intf.cpp b/backends/aptcc/apt-intf.cpp
index d6c447ab8..c1d15ebb7 100644
--- a/backends/aptcc/apt-intf.cpp
+++ b/backends/aptcc/apt-intf.cpp
@@ -363,7 +363,10 @@ PkgList AptIntf::filterPackages(const PkgList &packages, PkBitfield filters)
             for (const pkgCache::VerIterator &verIt : ret) {
                 bool found = false;
                 for (pkgAcquire::ItemIterator it = fetcher.ItemsBegin(); it < fetcher.ItemsEnd(); ++it) {
-                    pkgAcqArchiveSane *archive = static_cast<pkgAcqArchiveSane*>(*it);
+                    pkgAcqArchiveSane *archive = static_cast<pkgAcqArchiveSane*>(dynamic_cast<pkgAcqArchive*>(*it));
+                    if (archive == nullptr) {
+                        continue;
+                    }
                     const pkgCache::VerIterator ver = archive->version();
                     if ((*it)->Local && verIt == ver) {
                         found = true;
@@ -1516,7 +1519,10 @@ bool AptIntf::checkTrusted(pkgAcquire &fetcher, PkBitfield flags)
         if (!(*I)->IsTrusted()) {
             // The pkgAcquire::Item had a version hiden on it's subclass
             // pkgAcqArchive but it was protected our subclass exposes that
-            pkgAcqArchiveSane *archive = static_cast<pkgAcqArchiveSane*>(*I);
+            pkgAcqArchiveSane *archive = static_cast<pkgAcqArchiveSane*>(dynamic_cast<pkgAcqArchive*>(*I));
+            if (archive == nullptr) {
+                continue;
+            }
             untrusted.push_back(archive->version());
 
             UntrustedList += string((*I)->ShortDesc()) + " ";
-- 
2.15.1

