Просмотр исходного кода

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.
Tatsuhiro Tsujikawa 14 лет назад
Родитель
Сommit
7368c9c9d8
8 измененных файлов с 58 добавлено и 57 удалено
  1. 7 5
      src/FileEntry.cc
  2. 2 1
      src/HttpResponse.cc
  3. 2 23
      src/Request.cc
  4. 19 0
      src/util.cc
  5. 2 0
      src/util.h
  6. 18 0
      test/FileEntryTest.cc
  7. 8 0
      test/HttpResponseTest.cc
  8. 0 28
      test/RequestTest.cc

+ 7 - 5
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<std::string>& 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;

+ 2 - 1
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()));

+ 2 - 23
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);

+ 19 - 0
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) {

+ 2 - 0
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);

+ 18 - 0
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/file<with%2 %20space/"
+                             "file with space;param%?a=/?"));
+
+  CPPUNIT_ASSERT_EQUAL(std::string("http://host:80"
+                                   "/file%3Cwith%2%20%20space/"
+                                   "file%20with%20space;param%"
+                                   "?a=/?"),
+                       file.getRemainingUris()[1]);
 }
 
 void FileEntryTest::testAddUris()
@@ -239,6 +248,15 @@ void FileEntryTest::testInsertUri()
   CPPUNIT_ASSERT_EQUAL(std::string("http://example.org/3"), uris[1]);
   CPPUNIT_ASSERT_EQUAL(std::string("http://example.org/1"), uris[2]);
   CPPUNIT_ASSERT_EQUAL(std::string("http://example.org/4"), uris[3]);
+  // Test for percent-encode
+  CPPUNIT_ASSERT(file.insertUri("http://host:80/file<with%2 %20space/"
+                                "file with space;param%?a=/?", 0));
+
+  CPPUNIT_ASSERT_EQUAL(std::string("http://host:80"
+                                   "/file%3Cwith%2%20%20space/"
+                                   "file%20with%20space;param%"
+                                   "?a=/?"),
+                       file.getRemainingUris()[0]);
 }
 
 void FileEntryTest::testRemoveUri()

+ 8 - 0
test/HttpResponseTest.cc

@@ -494,6 +494,14 @@ void HttpResponseTest::testProcessRedirect()
 
   httpHeader->clearField();
 
+  // 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 {

+ 0 - 28
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<with%2 %20space/"
-                      "file with space;param%?a=/?");
-  CPPUNIT_ASSERT(v);
-  CPPUNIT_ASSERT_EQUAL(std::string("http"), req.getProtocol());
-  CPPUNIT_ASSERT_EQUAL(std::string("host"), req.getHost());
-  CPPUNIT_ASSERT_EQUAL(std::string("/file%3Cwith%2%20%20space"),
-                       req.getDir());
-  CPPUNIT_ASSERT_EQUAL(std::string("file%20with%20space;param%"),
-                       req.getFile());
-  CPPUNIT_ASSERT_EQUAL(std::string("?a=/?"), req.getQuery());
-  CPPUNIT_ASSERT_EQUAL(std::string("http://host:80/file%3Cwith%2%20%20space"
-                                   "/file%20with%20space;param%?a=/?"),
-                       req.getCurrentUri());
-  CPPUNIT_ASSERT_EQUAL(std::string("http://host:80/file<with%2 %20space"
-                                   "/file with space;param%?a=/?"),
-                       req.getUri());
-}
-
 void RequestTest::testRedirectUri()
 {
   Request req;
@@ -155,11 +132,6 @@ void RequestTest::testRedirectUri()
                                    "relativepath/to/file"),
                        req.getCurrentUri());
   CPPUNIT_ASSERT_EQUAL((unsigned int)3, req.getRedirectCount());
-
-  // White space in path and fragment is appended.
-  CPPUNIT_ASSERT(req.redirectUri("http://example.org/white space#aria2"));
-  CPPUNIT_ASSERT_EQUAL(std::string("http://example.org/white%20space"),
-                       req.getCurrentUri());
 }
 
 void RequestTest::testRedirectUri2()