]> git.saurik.com Git - apt.git/commitdiff
make http size check work
authorMichael Vogt <mvo@ubuntu.com>
Mon, 6 Oct 2014 15:42:39 +0000 (17:42 +0200)
committerMichael Vogt <mvo@ubuntu.com>
Mon, 6 Oct 2014 15:42:39 +0000 (17:42 +0200)
apt-pkg/acquire-method.cc
apt-pkg/acquire-method.h
apt-pkg/acquire-worker.cc
methods/http.cc
methods/http.h
methods/https.cc
methods/https.h
methods/server.cc
methods/server.h
test/integration/test-apt-update-expected-size [new file with mode: 0755]

index 82f2fb3ce091e51c9e11afe88f21bedc60bef096..330854e752adc655b6fa6f111a45c71acbd74757 100644 (file)
@@ -372,6 +372,8 @@ int pkgAcqMethod::Run(bool Single)
               if (hash.empty() == false)
                  Tmp->ExpectedHashes.push_back(HashString(*t, hash));
            }
+            char *End;
+            Tmp->ExpectedSize = strtoll(LookupTag(Message, "Expected-Size", "0").c_str(), &End, 10);
            Tmp->Next = 0;
            
            // Append it to the list
index cdeecc9a73983d602db3e304da750e6bcf9c7d3c..2e4e8281a978d92bb13c48fe2cdebaffabf2fad9 100644 (file)
@@ -48,6 +48,7 @@ class pkgAcqMethod
       bool IndexFile;
       bool FailIgnore;
       HashStringList ExpectedHashes;
+      unsigned long long ExpectedSize;
    };
    
    struct FetchResult
index 54be8e99fbda4d63f95b5e620477287cadcf92f2..8bd1618f4b09efb69fd49f0029e88c6b43c426cb 100644 (file)
@@ -526,6 +526,9 @@ bool pkgAcquire::Worker::QueueItem(pkgAcquire::Queue::QItem *Item)
    if (OutFd == -1)
       return false;
    
+   string ExpectedSize;
+   strprintf(ExpectedSize, "%llu", Item->Owner->FileSize);
+
    string Message = "600 URI Acquire\n";
    Message.reserve(300);
    Message += "URI: " + Item->URI;
@@ -533,6 +536,7 @@ bool pkgAcquire::Worker::QueueItem(pkgAcquire::Queue::QItem *Item)
    HashStringList const hsl = Item->Owner->HashSums();
    for (HashStringList::const_iterator hs = hsl.begin(); hs != hsl.end(); ++hs)
       Message += "\nExpected-" + hs->HashType() + ": " + hs->HashValue();
+   Message += "\nExpected-Size: " + ExpectedSize;
    Message += Item->Owner->Custom600Headers();
    Message += "\n\n";
    
index f2a4a4db631add976bcbf36d329a57d45d3304a5..b076e59ccc52f883fb96643acaef39f9d8550aa6 100644 (file)
@@ -64,7 +64,8 @@ const unsigned int CircleBuf::BW_HZ=10;
 // CircleBuf::CircleBuf - Circular input buffer                                /*{{{*/
 // ---------------------------------------------------------------------
 /* */
-CircleBuf::CircleBuf(unsigned long long Size) : Size(Size), Hash(0)
+CircleBuf::CircleBuf(unsigned long long Size) 
+   : Size(Size), Hash(0), TotalWriten(0)
 {
    Buf = new unsigned char[Size];
    Reset();
@@ -80,6 +81,7 @@ void CircleBuf::Reset()
    InP = 0;
    OutP = 0;
    StrPos = 0;
+   TotalWriten = 0;
    MaxGet = (unsigned long long)-1;
    OutQueue = string();
    if (Hash != 0)
@@ -217,6 +219,8 @@ bool CircleBuf::Write(int Fd)
         
         return false;
       }
+
+      TotalWriten += Res;
       
       if (Hash != 0)
         Hash->Add(Buf + (OutP%Size),Res);
@@ -651,6 +655,12 @@ bool HttpServerState::Go(bool ToFile, FileFd * const File)
         return _error->Errno("write",_("Error writing to output file"));
    }
 
+   if (ExpectedSize > 0 && File && File->Tell() > ExpectedSize)
+   {
+      return _error->Error("Writing more data than expected (%llu > %llu)",
+                           File->Tell(), ExpectedSize);
+   }
+
    // Handle commands from APT
    if (FD_ISSET(STDIN_FILENO,&rfds))
    {
index 1df9fa07d68c60849d375cb3a7cc952b6c144625..40a88a7be03b3a8e254b981ca6711f833c8173e7 100644 (file)
@@ -63,6 +63,8 @@ class CircleBuf
 
    public:
    Hashes *Hash;
+   // total amount of data that got written so far
+   unsigned long long TotalWriten;
 
    // Read data in
    bool Read(int Fd);
@@ -81,8 +83,8 @@ class CircleBuf
    bool ReadSpace() const {return Size - (InP - OutP) > 0;};
    bool WriteSpace() const {return InP - OutP > 0;};
 
-   // Dump everything
    void Reset();
+   // Dump everything
    void Stats();
 
    CircleBuf(unsigned long long Size);
index a74d2a38be4ba416ee7f1bfffbc1fdc3e43a9e0a..eec858417af0262c8496ea665f901274301515d1 100644 (file)
@@ -82,6 +82,12 @@ HttpsMethod::write_data(void *buffer, size_t size, size_t nmemb, void *userp)
    if(me->File->Write(buffer, size*nmemb) != true)
       return false;
 
+   me->TotalWritten += size*nmemb;
+   if(me->TotalWritten > me->Queue->ExpectedSize)
+      return _error->Error("Writing more data than expected (%llu > %llu)",
+                           me->TotalWritten, me->Queue->ExpectedSize);
+
+
    return size*nmemb;
 }
 
index 45d1f7f63a94858731e3659fa0742e8fc0ec3622..0387cb9b579764c4615808531630ce4007698145 100644 (file)
@@ -66,11 +66,12 @@ class HttpsMethod : public pkgAcqMethod
    CURL *curl;
    FetchResult Res;
    HttpsServerState *Server;
+   unsigned long long TotalWritten;
 
    public:
    FileFd *File;
-
-   HttpsMethod() : pkgAcqMethod("1.2",Pipeline | SendConfig), Server(NULL), File(NULL)
+      
+   HttpsMethod() : pkgAcqMethod("1.2",Pipeline | SendConfig), Server(NULL), TotalWritten(0), File(NULL)
    {
       curl = curl_easy_init();
    };
index 4a961f454df65bd152e29c75ed04afec920db620..2237379010d809544183a9ae96336ee315ccdf2d 100644 (file)
@@ -532,6 +532,11 @@ int ServerMethod::Loop()
 
            // Run the data
            bool Result = true;
+
+            // ensure we don't fetch too much
+            if (Queue->ExpectedSize > 0)
+               Server->ExpectedSize = Queue->ExpectedSize;
+
             if (Server->HaveContent)
               Result = Server->RunData(File);
 
@@ -605,7 +610,10 @@ int ServerMethod::Loop()
                  QueueBack = Queue;
               }
               else
+               {
+                  Server->Close();
                  Fail(true);
+               }
            }
            break;
         }
index aa692ea931ba5773a2dd8d4453916bfcb4793972..0134a95385cb60dc1eba9499cd0aa088a12ba587 100644 (file)
@@ -49,6 +49,8 @@ struct ServerState
    URI Proxy;
    unsigned long TimeOut;
 
+   unsigned long long ExpectedSize;
+
    protected:
    ServerMethod *Owner;
 
@@ -73,7 +75,7 @@ struct ServerState
    bool Comp(URI Other) const {return Other.Host == ServerName.Host && Other.Port == ServerName.Port;};
    virtual void Reset() {Major = 0; Minor = 0; Result = 0; Code[0] = '\0'; Size = 0;
                 StartPos = 0; Encoding = Closes; time(&Date); HaveContent = false;
-                State = Header; Persistent = false; Pipeline = true;};
+                State = Header; Persistent = false; Pipeline = true; ExpectedSize = 0;};
    virtual bool WriteResponse(std::string const &Data) = 0;
 
    /** \brief Transfer the data from the socket */
diff --git a/test/integration/test-apt-update-expected-size b/test/integration/test-apt-update-expected-size
new file mode 100755 (executable)
index 0000000..7281233
--- /dev/null
@@ -0,0 +1,27 @@
+#!/bin/sh
+set -e
+
+TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+
+setupenvironment
+configarchitecture "i386"
+
+insertpackage 'unstable' 'apt' 'all' '1.0'
+
+setupaptarchive --no-update
+changetowebserver
+
+# normal update works fine
+testsuccess aptget update
+
+# append junk at the end of the Packages.gz/Packages
+SIZE="$(stat --printf=%s aptarchive/dists/unstable/main/binary-i386/Packages)"
+echo "1234567890" >> aptarchive/dists/unstable/main/binary-i386/Packages.gz
+echo "1234567890" >> aptarchive/dists/unstable/main/binary-i386/Packages
+NEW_SIZE="$(stat --printf=%s aptarchive/dists/unstable/main/binary-i386/Packages)"
+rm -f rootdir/var/lib/apt/lists/localhost*
+testequal "W: Failed to fetch http://localhost:8080/dists/unstable/main/binary-i386/Packages  Writing more data than expected ($NEW_SIZE > $SIZE) [IP: ::1 8080]
+
+E: Some index files failed to download. They have been ignored, or old ones used instead." aptget update -qq
+