From 1c0fe94038537b4b7411b1c492493a57310beefb Mon Sep 17 00:00:00 2001 From: Amos Jeffries Date: Thu, 29 Oct 2009 20:50:40 +1300 Subject: [PATCH] Author: Alex Rousskov Bug 2791: assertion failed: MemBuf.cc:400: new_cap > (size_t) capacity Limit input buffer reads to the avilable space. --- src/Server.cc | 9 ++++++++- src/Server.h | 2 +- src/ftp.cc | 2 +- src/http.cc | 12 +++++------- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/Server.cc b/src/Server.cc index 476dfd8153..a34879f4b5 100644 --- a/src/Server.cc +++ b/src/Server.cc @@ -717,8 +717,15 @@ ServerStateData::storeReplyBody(const char *data, ssize_t len) currentOffset += len; } -size_t ServerStateData::replyBodySpace(size_t space) +size_t ServerStateData::replyBodySpace(const MemBuf &readBuf, + const size_t minSpace) const { + size_t space = readBuf.spaceSize(); // available space w/o heroic measures + if (space < minSpace) { + const size_t maxSpace = readBuf.potentialSpaceSize(); // absolute best + space = min(minSpace, maxSpace); // do not promise more than asked + } + #if ICAP_CLIENT if (responseBodyBuffer) { return 0; // Stop reading if already overflowed waiting for ICAP to catch up diff --git a/src/Server.h b/src/Server.h index e0aeb0b5c0..9f18ae1609 100644 --- a/src/Server.h +++ b/src/Server.h @@ -160,7 +160,7 @@ protected: void adaptOrFinalizeReply(); void addVirginReplyBody(const char *buf, ssize_t len); void storeReplyBody(const char *buf, ssize_t len); - size_t replyBodySpace(size_t space = 4096 * 10); + size_t replyBodySpace(const MemBuf &readBuf, const size_t minSpace) const; // These should be private int64_t currentOffset; // Our current offset in the StoreEntry diff --git a/src/ftp.cc b/src/ftp.cc index 9dc43bbca5..3545ee6b26 100644 --- a/src/ftp.cc +++ b/src/ftp.cc @@ -1204,7 +1204,7 @@ FtpStateData::maybeReadVirginBody() if (data.read_pending) return; - int read_sz = replyBodySpace(data.readBuf->spaceSize()); + const int read_sz = replyBodySpace(*data.readBuf, 0); debugs(11,9, HERE << "FTP may read up to " << read_sz << " bytes"); diff --git a/src/http.cc b/src/http.cc index 644a8f2568..1c8d2dba7a 100644 --- a/src/http.cc +++ b/src/http.cc @@ -1248,7 +1248,9 @@ HttpStateData::processReplyBody() void HttpStateData::maybeReadVirginBody() { - int read_sz = replyBodySpace(readBuf->spaceSize()); + // we may need to grow the buffer if headers do not fit + const int minRead = flags.headers_parsed ? 0 :1024; + const int read_sz = replyBodySpace(*readBuf, minRead); debugs(11,9, HERE << (flags.do_next_read ? "may" : "wont") << " read up to " << read_sz << " bytes from FD " << fd); @@ -1261,12 +1263,8 @@ HttpStateData::maybeReadVirginBody() * handler until we get a notification from someone that * its okay to read again. */ - if (read_sz < 2) { - if (flags.headers_parsed) - return; - else - read_sz = 1024; - } + if (read_sz < 2) + return; if (flags.do_next_read) { flags.do_next_read = 0; -- 2.47.2