summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apt-pkg/acquire-method.cc2
-rw-r--r--apt-pkg/acquire-method.h1
-rw-r--r--apt-pkg/acquire-worker.cc4
-rw-r--r--methods/http.cc12
-rw-r--r--methods/http.h4
-rw-r--r--methods/https.cc6
-rw-r--r--methods/https.h5
-rw-r--r--methods/server.cc8
-rw-r--r--methods/server.h4
-rwxr-xr-xtest/integration/test-apt-update-expected-size27
10 files changed, 68 insertions, 5 deletions
diff --git a/apt-pkg/acquire-method.cc b/apt-pkg/acquire-method.cc
index 82f2fb3ce..330854e75 100644
--- a/apt-pkg/acquire-method.cc
+++ b/apt-pkg/acquire-method.cc
@@ -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
diff --git a/apt-pkg/acquire-method.h b/apt-pkg/acquire-method.h
index cdeecc9a7..2e4e8281a 100644
--- a/apt-pkg/acquire-method.h
+++ b/apt-pkg/acquire-method.h
@@ -48,6 +48,7 @@ class pkgAcqMethod
bool IndexFile;
bool FailIgnore;
HashStringList ExpectedHashes;
+ unsigned long long ExpectedSize;
};
struct FetchResult
diff --git a/apt-pkg/acquire-worker.cc b/apt-pkg/acquire-worker.cc
index 54be8e99f..8bd1618f4 100644
--- a/apt-pkg/acquire-worker.cc
+++ b/apt-pkg/acquire-worker.cc
@@ -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";
diff --git a/methods/http.cc b/methods/http.cc
index f2a4a4db6..b076e59cc 100644
--- a/methods/http.cc
+++ b/methods/http.cc
@@ -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))
{
diff --git a/methods/http.h b/methods/http.h
index 1df9fa07d..40a88a7be 100644
--- a/methods/http.h
+++ b/methods/http.h
@@ -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);
diff --git a/methods/https.cc b/methods/https.cc
index a74d2a38b..eec858417 100644
--- a/methods/https.cc
+++ b/methods/https.cc
@@ -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;
}
diff --git a/methods/https.h b/methods/https.h
index 45d1f7f63..0387cb9b5 100644
--- a/methods/https.h
+++ b/methods/https.h
@@ -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();
};
diff --git a/methods/server.cc b/methods/server.cc
index 4a961f454..223737901 100644
--- a/methods/server.cc
+++ b/methods/server.cc
@@ -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;
}
diff --git a/methods/server.h b/methods/server.h
index aa692ea93..0134a9538 100644
--- a/methods/server.h
+++ b/methods/server.h
@@ -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
index 000000000..72812336d
--- /dev/null
+++ b/test/integration/test-apt-update-expected-size
@@ -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
+