Skip to content

Commit

Permalink
Port node's backslash support from
Browse files Browse the repository at this point in the history
  • Loading branch information
petkaantonov committed Dec 23, 2014
1 parent b04abc9 commit 7b97d30
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 14 deletions.
27 changes: 16 additions & 11 deletions src/urlparser.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ function Url$parse(str, parseQueryString, hostDenotesSlash) {
if (start <= end) {
var ch = str.charCodeAt(start);

if (ch === 0x2F /*'/'*/) {
if (ch === 0x2F /*'/'*/ || ch === 0x5C /*'\'*/) {
this._parsePath(str, start, end);
}
else if (ch === 0x3F /*'?'*/) {
Expand Down Expand Up @@ -484,8 +484,10 @@ Url.prototype._parsePort = function Url$_parsePort(str, start, end) {
Url.prototype._parseHost =
function Url$_parseHost(str, start, end, slashesDenoteHost) {
var hostEndingCharacters = this._hostEndingCharacters;
if (str.charCodeAt(start) === 0x2F /*'/'*/ &&
str.charCodeAt(start + 1) === 0x2F /*'/'*/) {
var first = str.charCodeAt(start);
var second = str.charCodeAt(start + 1);
if ((first === 0x2F /*'/'*/ || first === 0x5C /*'\'*/) &&
(second === 0x2F /*'/'*/ || second === 0x5C /*'\'*/)) {
this.slashes = true;

//The string starts with //
Expand Down Expand Up @@ -677,11 +679,12 @@ Url.prototype._clone = function Url$_clone() {
};

Url.prototype._getComponentEscaped =
function Url$_getComponentEscaped(str, start, end) {
function Url$_getComponentEscaped(str, start, end, isAfterHash) {
var cur = start;
var i = start;
var ret = "";
var autoEscapeMap = this._autoEscapeMap;
var autoEscapeMap = isAfterHash
? this._afterHashAutoEscapeMap : this._autoEscapeMap;
for (; i <= end; ++i) {
var ch = str.charCodeAt(i);
var escaped = autoEscapeMap[ch];
Expand Down Expand Up @@ -727,7 +730,7 @@ function Url$_parsePath(str, start, end) {

var path;
if (escape) {
path = this._getComponentEscaped(str, pathStart, pathEnd);
path = this._getComponentEscaped(str, pathStart, pathEnd, false);
}
else {
path = str.slice(pathStart, pathEnd + 1);
Expand Down Expand Up @@ -761,7 +764,7 @@ Url.prototype._parseQuery = function Url$_parseQuery(str, start, end) {

var query;
if (escape) {
query = this._getComponentEscaped(str, queryStart, queryEnd);
query = this._getComponentEscaped(str, queryStart, queryEnd, false);
}
else {
query = str.slice(queryStart, queryEnd + 1);
Expand All @@ -774,7 +777,7 @@ Url.prototype._parseHash = function Url$_parseHash(str, start, end) {
this.hash = "";
return;
}
this.hash = this._getComponentEscaped(str, start, end);
this.hash = this._getComponentEscaped(str, start, end, true);
};

Object.defineProperty(Url.prototype, "port", {
Expand Down Expand Up @@ -979,7 +982,8 @@ for (var i = 0, len = autoEscape.length; i < len; ++i) {
}
autoEscapeMap[c.charCodeAt(0)] = esc;
}

var afterHashAutoEscapeMap = autoEscapeMap.slice();
autoEscapeMap[0x5C /*'\'*/] = "/";

var slashProtocols = Url.prototype._slashProtocols = {
http: true,
Expand All @@ -1006,7 +1010,7 @@ Url.prototype._protocolCharacters = makeAsciiTable([
]);

Url.prototype._hostEndingCharacters = makeAsciiTable([
0x23 /*'#'*/, 0x3F /*'?'*/, 0x2F /*'/'*/
0x23 /*'#'*/, 0x3F /*'?'*/, 0x2F /*'/'*/, 0x5C /*'\'*/
]);

Url.prototype._autoEscapeCharacters = makeAsciiTable(
Expand All @@ -1019,14 +1023,15 @@ Url.prototype._autoEscapeCharacters = makeAsciiTable(
Url.prototype._noPrependSlashHostEnders = makeAsciiTable(
[
"<", ">", "'", "`", " ", "\r",
"\n", "\t", "{", "}", "|", "\\",
"\n", "\t", "{", "}", "|",
"^", "`", "\"", "%", ";"
].map(function(v) {
return v.charCodeAt(0);
})
);

Url.prototype._autoEscapeMap = autoEscapeMap;
Url.prototype._afterHashAutoEscapeMap = afterHashAutoEscapeMap;

module.exports = Url;

Expand Down
28 changes: 25 additions & 3 deletions test/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,28 @@ var url = require('../src/urlparser.js');
// URLs to parse, and expected data
// { url : parsed }
var parseTests = {
'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%5Ca%5Cs%5Ch',
href: 'http://evil-phisher/foo.html#h%5Ca%5Cs%5Ch'
},


'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'
},

'//some_path' : {
'href': '//some_path',
'pathname': '//some_path',
Expand Down Expand Up @@ -753,9 +775,9 @@ var parseTests = {
'host': 'x:1',
'port': '1',
'hostname': 'x',
'pathname': '/%27%20%3C%3E%22%60/%7B%7D%7C%5C%5E~%60/',
'path': '/%27%20%3C%3E%22%60/%7B%7D%7C%5C%5E~%60/',
'href': 'http://x:1/%27%20%3C%3E%22%60/%7B%7D%7C%5C%5E~%60/'
'pathname': '/%27%20%3C%3E%22%60/%7B%7D%7C/%5E~%60/',
'path': '/%27%20%3C%3E%22%60/%7B%7D%7C/%5E~%60/',
'href': 'http://x:1/%27%20%3C%3E%22%60/%7B%7D%7C/%5E~%60/'
},

'http://a@b@c/': {
Expand Down

0 comments on commit 7b97d30

Please sign in to comment.