From 7368c9c9d8515232204d3708a3e2233454368aec Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sun, 7 Aug 2011 20:46:04 +0900 Subject: [PATCH] Percent-encode non-printable ASCII and non-ASCII chars in FileEntry. Percent-encode non-printable ASCII and non-ASCII chars in URI using util::percentEncodeMini() when URI is added to FileEntry. Removed percent-encode from Request. Also do percent-encoding when setting referer and redirected URI. --- src/FileEntry.cc | 12 +++++++----- src/HttpResponse.cc | 3 ++- src/Request.cc | 25 ++----------------------- src/util.cc | 19 +++++++++++++++++++ src/util.h | 2 ++ test/FileEntryTest.cc | 18 ++++++++++++++++++ test/HttpResponseTest.cc | 8 ++++++++ test/RequestTest.cc | 28 ---------------------------- 8 files changed, 58 insertions(+), 57 deletions(-) diff --git a/src/FileEntry.cc b/src/FileEntry.cc index 3fa5a900..f214a015 100644 --- a/src/FileEntry.cc +++ b/src/FileEntry.cc @@ -155,7 +155,7 @@ FileEntry::getRequest req.reset(); continue; } - req->setReferer(referer); + req->setReferer(util::percentEncodeMini(referer)); req->setMethod(method); spentUris_.push_back(uri); inFlightRequests_.push_back(req); @@ -518,8 +518,9 @@ size_t FileEntry::setUris(const std::vector& uris) bool FileEntry::addUri(const std::string& uri) { uri::UriStruct us; - if(uri::parse(us, uri)) { - uris_.push_back(uri); + std::string peUri = util::percentEncodeMini(uri); + if(uri::parse(us, peUri)) { + uris_.push_back(peUri); return true; } else { return false; @@ -529,9 +530,10 @@ bool FileEntry::addUri(const std::string& uri) bool FileEntry::insertUri(const std::string& uri, size_t pos) { uri::UriStruct us; - if(uri::parse(us, uri)) { + std::string peUri = util::percentEncodeMini(uri); + if(uri::parse(us, peUri)) { pos = std::min(pos, uris_.size()); - uris_.insert(uris_.begin()+pos, uri); + uris_.insert(uris_.begin()+pos, peUri); return true; } else { return false; diff --git a/src/HttpResponse.cc b/src/HttpResponse.cc index 1cff01fd..8fce8932 100644 --- a/src/HttpResponse.cc +++ b/src/HttpResponse.cc @@ -160,7 +160,8 @@ bool HttpResponse::isRedirect() const void HttpResponse::processRedirect() { - if(httpRequest_->getRequest()->redirectUri(getRedirectURI())) { + if(httpRequest_->getRequest()->redirectUri + (util::percentEncodeMini(getRedirectURI()))) { A2_LOG_INFO(fmt(MSG_REDIRECT, cuid_, httpRequest_->getRequest()->getCurrentUri().c_str())); diff --git a/src/Request.cc b/src/Request.cc index 2b016685..a70f370e 100644 --- a/src/Request.cc +++ b/src/Request.cc @@ -85,27 +85,6 @@ std::string removeFragment(const std::string& uri) } } // namespace -namespace { -std::string percentEncode(const std::string& src) -{ - std::string result; - for(std::string::const_iterator i = src.begin(), eoi = src.end(); i != eoi; - ++i) { - // Non-Printable ASCII and non-ASCII chars + some ASCII chars. - unsigned char c = *i; - if(in(c, 0x00u, 0x20u) || c >= 0x7fu || - // Chromium escapes following characters. Firefox4 escapes - // more. - c == '"' || c == '<' || c == '>') { - result += fmt("%%%02X", c); - } else { - result += c; - } - } - return result; -} -} // namespace - bool Request::setUri(const std::string& uri) { supportsPersistentConnection_ = true; uri_ = uri; @@ -121,7 +100,7 @@ bool Request::resetUri() { void Request::setReferer(const std::string& uri) { - referer_ = previousUri_ = percentEncode(removeFragment(uri)); + referer_ = previousUri_ = removeFragment(uri); } bool Request::redirectUri(const std::string& uri) { @@ -145,7 +124,7 @@ bool Request::redirectUri(const std::string& uri) { } bool Request::parseUri(const std::string& srcUri) { - currentUri_ = percentEncode(removeFragment(srcUri)); + currentUri_ = removeFragment(srcUri); uri::UriStruct us; if(uri::parse(us, currentUri_)) { protocol_.swap(us.protocol); diff --git a/src/util.cc b/src/util.cc index 0fe52efa..9f96f571 100644 --- a/src/util.cc +++ b/src/util.cc @@ -447,6 +447,25 @@ std::string percentEncode(const std::string& target) target.size()); } +std::string percentEncodeMini(const std::string& src) +{ + std::string result; + for(std::string::const_iterator i = src.begin(), eoi = src.end(); i != eoi; + ++i) { + // Non-Printable ASCII and non-ASCII chars + some ASCII chars. + unsigned char c = *i; + if(in(c, 0x00u, 0x20u) || c >= 0x7fu || + // Chromium escapes following characters. Firefox4 escapes + // more. + c == '"' || c == '<' || c == '>') { + result += fmt("%%%02X", c); + } else { + result += c; + } + } + return result; +} + std::string torrentPercentEncode(const unsigned char* target, size_t len) { std::string dest; for(size_t i = 0; i < len; ++i) { diff --git a/src/util.h b/src/util.h index 09e8e63f..049fa7a1 100644 --- a/src/util.h +++ b/src/util.h @@ -170,6 +170,8 @@ std::string percentEncode(const unsigned char* target, size_t len); std::string percentEncode(const std::string& target); +std::string percentEncodeMini(const std::string& target); + bool inRFC3986ReservedChars(const char c); bool inRFC3986UnreservedChars(const char c); diff --git a/test/FileEntryTest.cc b/test/FileEntryTest.cc index bc9aed62..bcfe819d 100644 --- a/test/FileEntryTest.cc +++ b/test/FileEntryTest.cc @@ -218,6 +218,15 @@ void FileEntryTest::testAddUri() FileEntry file; CPPUNIT_ASSERT(file.addUri("http://good")); CPPUNIT_ASSERT(!file.addUri("bad")); + // Test for percent-encode + CPPUNIT_ASSERT(file.addUri("http://host:80/fileclearField(); + // Test for percent-encode + httpHeader->put("Location", "http://example.org/white space#aria2"); + httpResponse.processRedirect(); + CPPUNIT_ASSERT_EQUAL(std::string("http://example.org/white%20space"), + request->getCurrentUri()); + + httpHeader->clearField(); + // Give unsupported scheme httpHeader->put("Location", "unsupported://mirror/aria2-1.0.0.tar.bz2"); try { diff --git a/test/RequestTest.cc b/test/RequestTest.cc index 3b361532..33c213d3 100644 --- a/test/RequestTest.cc +++ b/test/RequestTest.cc @@ -15,7 +15,6 @@ class RequestTest:public CppUnit::TestFixture { CPPUNIT_TEST(testSetUri1); CPPUNIT_TEST(testSetUri2); CPPUNIT_TEST(testSetUri7); - CPPUNIT_TEST(testSetUri17); CPPUNIT_TEST(testSetUri_supportsPersistentConnection); CPPUNIT_TEST(testRedirectUri); CPPUNIT_TEST(testRedirectUri2); @@ -31,7 +30,6 @@ public: void testSetUri1(); void testSetUri2(); void testSetUri7(); - void testSetUri17(); void testSetUri_supportsPersistentConnection(); void testRedirectUri(); void testRedirectUri2(); @@ -94,27 +92,6 @@ void RequestTest::testSetUri7() { CPPUNIT_ASSERT(!v); } -void RequestTest::testSetUri17() -{ - Request req; - bool v = req.setUri("http://host:80/file