url: treat \ the same as /
authorisaacs <i@izs.me>
Tue, 25 Mar 2014 21:16:55 +0000 (14:16 -0700)
committerisaacs <i@izs.me>
Tue, 15 Apr 2014 22:30:43 +0000 (15:30 -0700)
See https://code.google.com/p/chromium/issues/detail?id=25916

Parse URLs with backslashes the same as web browsers, by replacing all
backslashes with forward slashes, except those that occur after the
first # character.

lib/url.js
test/simple/test-url.js

index 09e9cce..c13f74b 100644 (file)
@@ -107,6 +107,12 @@ Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) {
     throw new TypeError("Parameter 'url' must be a string, not " + typeof url);
   }
 
+  // Copy chrome, IE, opera backslash-handling behavior.
+  // See: https://code.google.com/p/chromium/issues/detail?id=25916
+  var hashSplit = url.split('#');
+  hashSplit[0] = hashSplit[0].replace(/\\/g, '/');
+  url = hashSplit.join('#');
+
   var rest = url;
 
   // trim before proceeding.
index 57d0a6d..95f50a2 100644 (file)
@@ -34,6 +34,28 @@ var parseTests = {
     'path': '//some_path'
   },
 
+  'http:\\\\evil-phisher\\foo.html#h\\a\\s\\h': {
+    protocol: 'http:',
+    slashes: true,
+    host: 'evil-phisher',
+    hostname: 'evil-phisher',
+    pathname: '/foo.html',
+    path: '/foo.html',
+    hash: '#h\\a\\s\\h',
+    href: 'http://evil-phisher/foo.html#h\\a\\s\\h'
+  },
+
+
+  'http:\\\\evil-phisher\\foo.html': {
+    protocol: 'http:',
+    slashes: true,
+    host: 'evil-phisher',
+    hostname: 'evil-phisher',
+    pathname: '/foo.html',
+    path: '/foo.html',
+    href: 'http://evil-phisher/foo.html'
+  },
+
   'HTTP://www.example.com/' : {
     'href': 'http://www.example.com/',
     'protocol': 'http:',
@@ -1457,3 +1479,7 @@ relativeTests2.forEach(function(relativeTest) {
                'format(' + relativeTest[1] + ') == ' + expected +
                '\nactual:' + actual);
 });
+
+// backslashes should be like forward slashes
+var res = url.resolve('http://example.com/x', '\\\\foo.com\\bar');
+assert.equal(res, 'http://foo.com/bar');