diff -Nru apt-0.9.7.5ubuntu5.4/apt-pkg/acquire-worker.cc apt-0.9.7.5ubuntu5.5/apt-pkg/acquire-worker.cc --- apt-0.9.7.5ubuntu5.4/apt-pkg/acquire-worker.cc 2013-08-21 12:49:35.000000000 -0500 +++ apt-0.9.7.5ubuntu5.5/apt-pkg/acquire-worker.cc 2013-08-21 12:57:50.000000000 -0500 @@ -305,7 +305,15 @@ OwnerQ->ItemDone(Itm); unsigned long long const ServerSize = strtoull(LookupTag(Message,"Size","0").c_str(), NULL, 10); - if (TotalSize != 0 && ServerSize != TotalSize) + bool isHit = StringToBool(LookupTag(Message,"IMS-Hit"),false) || + StringToBool(LookupTag(Message,"Alt-IMS-Hit"),false); + // Using the https method the server might return 200, but the + // If-Modified-Since condition is not satsified, libcurl will + // discard the download. In this case, however, TotalSize will be + // set to the actual size of the file, while ServerSize will be set + // to 0. Therefore, if the item is marked as a hit and the + // downloaded size (ServerSize) is 0, we ignore TotalSize. + if (TotalSize != 0 && (!isHit || ServerSize != 0) && ServerSize != TotalSize) _error->Warning("Size of file %s is not what the server reported %s %llu", Owner->DestFile.c_str(), LookupTag(Message,"Size","0").c_str(),TotalSize); @@ -332,8 +340,7 @@ // Log that we are done if (Log != 0) { - if (StringToBool(LookupTag(Message,"IMS-Hit"),false) == true || - StringToBool(LookupTag(Message,"Alt-IMS-Hit"),false) == true) + if (isHit) { /* Hide 'hits' for local only sources - we also manage to hide gets */ diff -Nru apt-0.9.7.5ubuntu5.4/debian/changelog apt-0.9.7.5ubuntu5.5/debian/changelog --- apt-0.9.7.5ubuntu5.4/debian/changelog 2013-08-21 12:49:35.000000000 -0500 +++ apt-0.9.7.5ubuntu5.5/debian/changelog 2013-08-21 13:14:24.000000000 -0500 @@ -1,3 +1,9 @@ +apt (0.9.7.5ubuntu5.5) quantal; urgency=low + + * If-modified-since unhandled case causes apt lists corruption (LP: #1179781) + + -- Dave Chiluk Wed, 21 Aug 2013 13:14:06 -0500 + apt (0.9.7.5ubuntu5.4) quantal-security; urgency=low * SECURITY UPDATE: InRelease verification bypass diff -Nru apt-0.9.7.5ubuntu5.4/debian/control apt-0.9.7.5ubuntu5.5/debian/control --- apt-0.9.7.5ubuntu5.4/debian/control 2013-08-21 12:49:35.000000000 -0500 +++ apt-0.9.7.5ubuntu5.5/debian/control 2013-08-30 14:04:24.000000000 -0500 @@ -120,7 +120,7 @@ Package: apt-transport-https Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends} +Depends: ${shlibs:Depends}, ${misc:Depends}, libcurl3-gnutls (>= 7.27.0-1ubuntu1.4) Priority: optional Description: https download transport for APT This package enables the usage of 'deb https://foo distro main' lines diff -Nru apt-0.9.7.5ubuntu5.4/methods/https.cc apt-0.9.7.5ubuntu5.5/methods/https.cc --- apt-0.9.7.5ubuntu5.4/methods/https.cc 2013-08-21 12:49:35.000000000 -0500 +++ apt-0.9.7.5ubuntu5.5/methods/https.cc 2013-08-21 12:57:50.000000000 -0500 @@ -285,6 +285,11 @@ long curl_servdate; curl_easy_getinfo(curl, CURLINFO_FILETIME, &curl_servdate); + // If the server returns 200 OK but the If-Modified-Since condition is not + // met, CURLINFO_CONDITION_UNMET will be set to 1 + long curl_condition_unmet = 0; + curl_easy_getinfo(curl, CURLINFO_CONDITION_UNMET, &curl_condition_unmet); + File->Close(); // cleanup @@ -312,7 +317,7 @@ Res.Filename = File->Name(); Res.LastModified = Buf.st_mtime; Res.IMSHit = false; - if (curl_responsecode == 304) + if (curl_responsecode == 304 || curl_condition_unmet) { unlink(File->Name().c_str()); Res.IMSHit = true;