Browse Source

2007-07-18 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

	Fixed the bug that prevents filename in content-disposition from
	being retrieved when filename is not quoted.
	* src/Util.cc (getContentDispositionFilename)

	Fixed the bug that causes infinate loop and memory leak when 
file open
	operation failed.
	* src/HttpResponseCommand.cc (handleDefaultEncoding)
Tatsuhiro Tsujikawa 18 years ago
parent
commit
247b1f2a4f
5 changed files with 63 additions and 15 deletions
  1. 10 0
      ChangeLog
  2. 11 6
      src/HttpResponseCommand.cc
  3. 19 8
      src/Util.cc
  4. 1 1
      src/Util.h
  5. 22 0
      test/UtilTest.cc

+ 10 - 0
ChangeLog

@@ -1,3 +1,13 @@
+2007-07-18  Tatsuhiro Tsujikawa  <tujikawa at rednoah dot com>
+
+	Fixed the bug that prevents filename in content-disposition from
+	being retrieved when filename is not quoted.
+	* src/Util.cc (getContentDispositionFilename)
+
+	Fixed the bug that causes infinate loop and memory leak when file open
+	operation failed.
+	* src/HttpResponseCommand.cc (handleDefaultEncoding)
+
 2007-07-09  Tatsuhiro Tsujikawa  <tujikawa at rednoah dot com>
 
 	Fixed the bug that causes segfault when all URIs specified are

+ 11 - 6
src/HttpResponseCommand.cc

@@ -142,13 +142,18 @@ bool HttpResponseCommand::handleDefaultEncoding(const HttpResponseHandle& httpRe
   }
 
   DownloadCommand* command = 0;
-  File file(_requestGroup->getFilePath());
-  if(_requestGroup->getRemainingUris().empty() && !file.exists()) {
-    command = createHttpDownloadCommand(httpResponse);
+  try {
+    File file(_requestGroup->getFilePath());
+    if(_requestGroup->getRemainingUris().empty() && !file.exists()) {
+      command = createHttpDownloadCommand(httpResponse);
+    }
+    _requestGroup->loadAndOpenFile();
+    _requestGroup->prepareForNextAction(cuid, req, e, command);
+    e->noWait = true;
+  } catch(Exception* e) {
+    delete command;
+    throw;
   }
-  _requestGroup->loadAndOpenFile();
-  _requestGroup->prepareForNextAction(cuid, req, e, command);
-  e->noWait = true;
   return true;
 }
 

+ 19 - 8
src/Util.cc

@@ -111,9 +111,9 @@ string Util::llitos(int64_t value, bool comma)
   return int2str<int64_t>(value, comma);
 }
 
-string Util::trim(const string& src) {
-  string::size_type sp = src.find_first_not_of("\r\n\t ");
-  string::size_type ep = src.find_last_not_of("\r\n\t ");
+string Util::trim(const string& src, const string& trimCharset) {
+  string::size_type sp = src.find_first_not_of(trimCharset);
+  string::size_type ep = src.find_last_not_of(trimCharset);
   if(sp == string::npos || ep == string::npos) {
     return "";
   } else {
@@ -459,16 +459,27 @@ void Util::unfoldRange(const string& src, Integers& range) {
 }
 
 string Util::getContentDispositionFilename(const string& header) {
-  string::size_type attributesp = header.find("filename=\"");
+  string keyName = "filename=";
+  string::size_type attributesp = header.find(keyName);
   if(attributesp == string::npos) {
     return "";
   }
-  string::size_type filenamesp = attributesp+strlen("filename=\"");
-  string::size_type filenameep = header.find("\"", filenamesp);
-  if(filenameep == string::npos) {
+  string::size_type filenamesp = attributesp+strlen(keyName.c_str());
+  string::size_type filenameep;
+  if(filenamesp == header.size()) {
     return "";
   }
-  return trim(header.substr(filenamesp, filenameep-filenamesp));
+  
+  if(header[filenamesp] == '\'' || header[filenamesp] == '"') {
+    char quoteChar = header[filenamesp];
+    filenameep = header.find(quoteChar, filenamesp+1);
+  } else {
+    filenameep = header.find(';', filenamesp);
+  }
+  if(filenameep == string::npos) {
+    filenameep = header.size();
+  }
+  return trim(header.substr(filenamesp, filenameep-filenamesp), "\r\n '\"");
 }
 
 #ifdef ENABLE_MESSAGE_DIGEST

+ 1 - 1
src/Util.h

@@ -73,7 +73,7 @@ public:
    */
   static void slice(Strings& result, const string& src, char delim, bool trim = false);
   
-  static string trim(const string& src);
+  static string trim(const string& src, const string& trimCharset = "\r\n\t ");
 
   static bool startsWith(const string& target, const string& part);
 

+ 22 - 0
test/UtilTest.cc

@@ -203,6 +203,28 @@ void UtilTest::testGetContentDispositionFilename() {
 
   string h4 = "attachment;";
   CPPUNIT_ASSERT_EQUAL(string(""), Util::getContentDispositionFilename(h4));
+
+  string h5 = "attachment; filename=aria2.tar.bz2";
+  CPPUNIT_ASSERT_EQUAL(string("aria2.tar.bz2"), Util::getContentDispositionFilename(h5));
+
+  string h6 = "attachment; filename='aria2.tar.bz2'";
+  CPPUNIT_ASSERT_EQUAL(string("aria2.tar.bz2"), Util::getContentDispositionFilename(h6));
+
+  string h7 = "attachment; filename='aria2.tar.bz2";
+  CPPUNIT_ASSERT_EQUAL(string("aria2.tar.bz2"), Util::getContentDispositionFilename(h7));
+
+  string h8 = "attachment; filename=aria2.tar.bz2; creation-date=20 Jun 2007 00:00:00 GMT";
+  CPPUNIT_ASSERT_EQUAL(string("aria2.tar.bz2"), Util::getContentDispositionFilename(h8));
+
+  string h9 = "attachment; filename=\"aria2.tar.bz2; creation-date=20 Jun 2007 00:00:00 GMT\"";
+  CPPUNIT_ASSERT_EQUAL(string("aria2.tar.bz2; creation-date=20 Jun 2007 00:00:00 GMT"), Util::getContentDispositionFilename(h9));
+
+  string h10 = "attachment; filename=";
+  CPPUNIT_ASSERT_EQUAL(string(""), Util::getContentDispositionFilename(h10));
+
+  string h11 = "attachment; filename=;";
+  CPPUNIT_ASSERT_EQUAL(string(""), Util::getContentDispositionFilename(h11));
+
 }
 
 class Printer {