Prechádzať zdrojové kódy

2008-09-14 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

	Added upper limit of FTP response buffer. The current 
implementation
	uses 4096bytes as a limit.
	* src/FtpConnection.cc
	* src/FtpConnection.h
	* test/FtpConnectionTest.cc
Tatsuhiro Tsujikawa 17 rokov pred
rodič
commit
479a16edd6
4 zmenil súbory, kde vykonal 38 pridanie a 3 odobranie
  1. 8 0
      ChangeLog
  2. 7 3
      src/FtpConnection.cc
  3. 1 0
      src/FtpConnection.h
  4. 22 0
      test/FtpConnectionTest.cc

+ 8 - 0
ChangeLog

@@ -1,3 +1,11 @@
+2008-09-14  Tatsuhiro Tsujikawa  <tujikawa at rednoah dot com>
+
+	Added upper limit of FTP response buffer. The current implementation
+	uses 4096bytes as a limit.
+	* src/FtpConnection.cc
+	* src/FtpConnection.h
+	* test/FtpConnectionTest.cc
+	
 2008-09-14  Tatsuhiro Tsujikawa  <tujikawa at rednoah dot com>
 
 	Use non-blocking socket for TCP communication to avoid possible

+ 7 - 3
src/FtpConnection.cc

@@ -47,6 +47,7 @@
 #include "DlAbortEx.h"
 #include "Socket.h"
 #include "A2STR.h"
+#include "StringFormat.h"
 #include <cstring>
 #include <cassert>
 
@@ -265,13 +266,16 @@ bool FtpConnection::bulkReceiveResponse(std::pair<unsigned int, std::string>& re
 {
   char buf[1024];  
   while(socket->isReadable(0)) {
-    size_t size = sizeof(buf)-1;
+    size_t size = sizeof(buf);
     socket->readData(buf, size);
     if(size == 0) {
       throw DlRetryEx(EX_GOT_EOF);
     }
-    buf[size] = '\0';
-    strbuf += buf;
+    if(strbuf.size()+size > MAX_RECV_BUFFER) {
+      throw DlRetryEx(StringFormat("Max FTP recv buffer reached. length=%zu",
+				   strbuf.size()+size).str());
+    }
+    strbuf.append(&buf[0], &buf[size]);
   }
   unsigned int status;
   if(strbuf.size() >= 4) {

+ 1 - 0
src/FtpConnection.h

@@ -71,6 +71,7 @@ private:
 
   static const std::string I;
 
+  static const size_t MAX_RECV_BUFFER = 4096;
 public:
   FtpConnection(int32_t cuid, const SharedHandle<SocketCore>& socket,
 		const SharedHandle<Request>& req, const Option* op);

+ 22 - 0
test/FtpConnectionTest.cc

@@ -4,7 +4,9 @@
 #include "SocketCore.h"
 #include "Request.h"
 #include "Option.h"
+#include "DlRetryEx.h"
 #include <iostream>
+#include <cstring>
 #include <cppunit/extensions/HelperMacros.h>
 
 namespace aria2 {
@@ -13,6 +15,7 @@ class FtpConnectionTest:public CppUnit::TestFixture {
 
   CPPUNIT_TEST_SUITE(FtpConnectionTest);
   CPPUNIT_TEST(testReceiveResponse);
+  CPPUNIT_TEST(testReceiveResponse_overflow);
   CPPUNIT_TEST(testSendMdtm);
   CPPUNIT_TEST(testReceiveMdtmResponse);
   CPPUNIT_TEST_SUITE_END();
@@ -50,6 +53,7 @@ public:
   void testSendMdtm();
   void testReceiveMdtmResponse();
   void testReceiveResponse();
+  void testReceiveResponse_overflow();
 };
 
 
@@ -137,4 +141,22 @@ void FtpConnectionTest::testReceiveMdtmResponse()
   }
 }
 
+void FtpConnectionTest::testReceiveResponse_overflow()
+{
+  char data[1024];
+  memset(data, 0, sizeof(data));
+  memcpy(data, "213 ", 4);
+  for(int i = 0; i < 4; ++i) {
+    _serverSocket->writeData(data, sizeof(data));
+    CPPUNIT_ASSERT_EQUAL((unsigned int)0, _ftp->receiveResponse());
+  }
+  _serverSocket->writeData(data, sizeof(data));
+  try {
+    _ftp->receiveResponse();
+    CPPUNIT_FAIL("exception must be thrown.");
+  } catch(DlRetryEx& e) {
+    // success
+  }
+}
+
 } // namespace aria2