Prechádzať zdrojové kódy

Only percent-encode non-printable ASCII chars(0x00-0x1f), non-ASCII
chars(>0x7f), ' ', '"', '<' and '>' for URIs supplied by user and
remote server(usually Location header field).

Tatsuhiro Tsujikawa 14 rokov pred
rodič
commit
2799c9f0cc
2 zmenil súbory, kde vykonal 16 pridanie a 22 odobranie
  1. 12 18
      src/Request.cc
  2. 4 4
      test/RequestTest.cc

+ 12 - 18
src/Request.cc

@@ -88,26 +88,20 @@ std::string removeFragment(const std::string& uri)
 namespace {
 std::string percentEncode(const std::string& src)
 {
-  std::string result = src;
-  if(src.empty()) {
-    return result;
-  }
-  result += "  ";
-  for(int index = src.size()-1; index >= 0; --index) {
-    const unsigned char c = result[index];
-    // '/' is not percent encoded because src is expected to be a path.
-    if(!util::inRFC3986ReservedChars(c) && !util::inRFC3986UnreservedChars(c)) {
-      if(c == '%') {
-        if(!util::isHexDigit(result[index+1]) ||
-           !util::isHexDigit(result[index+2])) {
-          result.replace(index, 1, "%25");
-        }
-      } else {
-        result.replace(index, 1, fmt("%%%02X", c));
-      }
+  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, 0x1fu) || c >= 0x7fu ||
+       // Chromium escapes following characters. Firefox4 escapes
+       // more.
+       c == ' ' || c == '"' || c == '<' || c == '>') {
+      result += fmt("%%%02X", c);
+    } else {
+      result += c;
     }
   }
-  result.erase(result.size()-2);
   return result;
 }
 } // namespace

+ 4 - 4
test/RequestTest.cc

@@ -102,13 +102,13 @@ void RequestTest::testSetUri17()
   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%252%20%20space"),
+  CPPUNIT_ASSERT_EQUAL(std::string("/file%3Cwith%2%20%20space"),
                        req.getDir());
-  CPPUNIT_ASSERT_EQUAL(std::string("file%20with%20space;param%25"),
+  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%252%20%20space"
-                                   "/file%20with%20space;param%25?a=/?"),
+  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=/?"),