From f1017d5def6af26f0bb988de8e9790c58afed2fa Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Thu, 28 Jun 2012 23:18:50 +0900 Subject: [PATCH] Don't percent-decode filename value in Content-Disposition. We only percent-decode filename* value in Content-Disposition because the encoding is fully specified. But since filename value is not, so we just accept it as is. --- src/util.cc | 5 +++-- test/UtilTest.cc | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/util.cc b/src/util.cc index bdd3fe21..e5686a14 100644 --- a/src/util.cc +++ b/src/util.cc @@ -929,8 +929,9 @@ std::string getContentDispositionFilename(const std::string& header) filenameLast = value.end(); } static const std::string TRIMMED("\r\n\t '\""); - value = percentDecode(value.begin(), filenameLast); - value = strip(value, TRIMMED); + std::pair vi = + util::stripIter(value.begin(), filenameLast, TRIMMED); + value.assign(vi.first, vi.second); value.erase(std::remove(value.begin(), value.end(), '\\'), value.end()); if(!detectDirTraversal(value) && value.find("/") == std::string::npos) { filename = value; diff --git a/test/UtilTest.cc b/test/UtilTest.cc index 1005c75e..ab193d29 100644 --- a/test/UtilTest.cc +++ b/test/UtilTest.cc @@ -872,8 +872,10 @@ void UtilTest::testGetContentDispositionFilename() { CPPUNIT_ASSERT_EQUAL(std::string("foo;bar"), util::getContentDispositionFilename(semicolonInside)); + // Unescaping %2E%2E%2F produces "../". But since we won't unescape, + // we just accept it as is. CPPUNIT_ASSERT_EQUAL - (std::string(""), + (std::string("%2E%2E%2Ffoo.html"), util::getContentDispositionFilename("filename=\"%2E%2E%2Ffoo.html\"")); // RFC2231 Section4