summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2010-05-06 12:49:50 +0000
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2010-05-06 12:49:50 +0000
commit2bcf6481022b7fa9726df46b5a665a6a3f4eafe2 (patch)
tree0ac797061bf92f275eff69626ee693b2771fc36c
parentd9f0c3da92a4e90fea2091dd4d2d02d082b0310e (diff)
2010-05-06 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Fixed the bug that if filename in Content-Disposition header includes ';', aria2 cuts filename after ';'. * src/util.cc * test/UtilTest.cc
-rw-r--r--ChangeLog7
-rw-r--r--src/util.cc41
-rw-r--r--test/UtilTest.cc7
3 files changed, 53 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index dea04061..6eaa6f91 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2010-05-06 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
+
+ Fixed the bug that if filename in Content-Disposition header
+ includes ';', aria2 cuts filename after ';'.
+ * src/util.cc
+ * test/UtilTest.cc
+
2010-04-28 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Release 1.9.2
diff --git a/src/util.cc b/src/util.cc
index 58a37d4a..11f89f57 100644
--- a/src/util.cc
+++ b/src/util.cc
@@ -679,11 +679,50 @@ std::string iso8859ToUtf8(const std::string& src)
return dest;
}
+template<typename OutputIterator>
+static void parseParam(OutputIterator out, const std::string& header)
+{
+ for(std::string::const_iterator i = header.begin(), eoi = header.end();
+ i != eoi;) {
+ std::string::const_iterator paramFirst = i;
+ std::string::const_iterator paramLast = paramFirst;
+ for(; paramLast != eoi && *paramLast != '=' && *paramLast != ';';
+ ++paramLast);
+ std::string param;
+ if(paramLast == eoi || *paramLast == ';') {
+ // No value, parmname only
+ param = std::string(paramFirst, paramLast);
+ } else {
+ for(; paramLast != eoi && *paramLast != '"' && *paramLast != ';';
+ ++paramLast);
+ if(paramLast != eoi && *paramLast == '"') {
+ // quoted-string
+ ++paramLast;
+ for(; paramLast != eoi && *paramLast != '"'; ++paramLast);
+ if(paramLast != eoi) {
+ ++paramLast;
+ }
+ param = std::string(paramFirst, paramLast);
+ for(; paramLast != eoi && *paramLast != ';'; ++paramLast);
+ } else {
+ param = std::string(paramFirst, paramLast);
+ }
+ }
+ trimSelf(param);
+ *out++ = param;
+ if(paramLast == eoi) {
+ break;
+ }
+ i = paramLast;
+ ++i;
+ }
+}
+
std::string getContentDispositionFilename(const std::string& header)
{
std::string filename;
std::vector<std::string> params;
- split(header, std::back_inserter(params), A2STR::SEMICOLON_C, true);
+ parseParam(std::back_inserter(params), header);
for(std::vector<std::string>::const_iterator i = params.begin(),
eoi = params.end(); i != eoi; ++i) {
const std::string& param = *i;
diff --git a/test/UtilTest.cc b/test/UtilTest.cc
index 25c187de..ddbc4fec 100644
--- a/test/UtilTest.cc
+++ b/test/UtilTest.cc
@@ -301,7 +301,7 @@ void UtilTest::testGetContentDispositionFilename() {
CPPUNIT_ASSERT_EQUAL(std::string("aria2.tar.bz2"), util::getContentDispositionFilename(h8));
std::string h9 = "attachment; filename=\"aria2.tar.bz2; creation-date=20 Jun 2007 00:00:00 GMT\"";
- CPPUNIT_ASSERT_EQUAL(std::string("aria2.tar.bz2"),
+ CPPUNIT_ASSERT_EQUAL(std::string("aria2.tar.bz2; creation-date=20 Jun 2007 00:00:00 GMT"),
util::getContentDispositionFilename(h9));
std::string h10 = "attachment; filename=";
@@ -313,6 +313,11 @@ void UtilTest::testGetContentDispositionFilename() {
std::string filenameWithDir = "attachment; filename=dir/file";
CPPUNIT_ASSERT_EQUAL(std::string(""),
util::getContentDispositionFilename(filenameWithDir));
+
+ std::string semicolonInside = "attachment; filename=\"foo;bar\"";
+ CPPUNIT_ASSERT_EQUAL(std::string("foo;bar"),
+ util::getContentDispositionFilename(semicolonInside));
+
CPPUNIT_ASSERT_EQUAL
(std::string(""),
util::getContentDispositionFilename("filename=\"%2E%2E%2Ffoo.html\""));