fast-url-parser
Advanced tools
+10
-74
| "use strict"; | ||
| Error.stackTraceLimit = 100; | ||
| var astPasses = require("./ast_passes.js"); | ||
| module.exports = function( grunt ) { | ||
| var isCI = !!grunt.option("ci"); | ||
| var license; | ||
| function getLicense() { | ||
| if( !license ) { | ||
| var fs = require("fs"); | ||
| var text = fs.readFileSync("LICENSE", "utf8"); | ||
| text = text.split("\n").map(function(line, index){ | ||
| return " * " + line; | ||
| }).join("\n") | ||
| license = "/**\n" + text + "\n */\n"; | ||
| } | ||
| return license | ||
| } | ||
| function writeFile( dest, content ) { | ||
@@ -28,21 +12,2 @@ grunt.file.write( dest, content ); | ||
| var getGlobals = function() { | ||
| var fs = require("fs"); | ||
| var file = "./src/constants.js"; | ||
| var contents = fs.readFileSync(file, "utf8"); | ||
| var rconstantname = /CONSTANT\(\s*([^,]+)/g; | ||
| var m; | ||
| var globals = { | ||
| "console": false, | ||
| "require": false, | ||
| "module": false, | ||
| "define": false, | ||
| "escape": false | ||
| }; | ||
| while( ( m = rconstantname.exec( contents ) ) ) { | ||
| globals[m[1]] = false; | ||
| } | ||
| return globals; | ||
| } | ||
| gruntConfig.pkg = grunt.file.readJSON("package.json"); | ||
@@ -53,3 +18,9 @@ | ||
| options: { | ||
| globals: getGlobals(), | ||
| globals: { | ||
| "console": false, | ||
| "require": false, | ||
| "module": false, | ||
| "define": false, | ||
| "escape": false | ||
| }, | ||
@@ -117,42 +88,7 @@ "bitwise": false, | ||
| if( !isCI ) { | ||
| gruntConfig.jshint.all.options.reporter = require("jshint-stylish"); | ||
| } | ||
| gruntConfig.bump = { | ||
| options: { | ||
| files: ['package.json'], | ||
| updateConfigs: [], | ||
| commit: true, | ||
| commitMessage: 'Release v%VERSION%', | ||
| commitFiles: ['-a'], | ||
| createTag: true, | ||
| tagName: 'v%VERSION%', | ||
| tagMessage: 'Version %VERSION%', | ||
| false: true, | ||
| pushTo: 'master', | ||
| gitDescribeOptions: '--tags --always --abbrev=1 --dirty=-d' // options to use with '$ git describe' | ||
| } | ||
| }; | ||
| gruntConfig.jshint.all.options.reporter = require("jshint-stylish"); | ||
| grunt.initConfig(gruntConfig); | ||
| grunt.loadNpmTasks('grunt-contrib-jshint'); | ||
| grunt.loadNpmTasks('grunt-bump'); | ||
| grunt.registerTask( "build", function() { | ||
| var fs = require("fs"); | ||
| var CONSTANTS_FILE = "./src/constants.js"; | ||
| astPasses.readConstants(fs.readFileSync(CONSTANTS_FILE, "utf8"), CONSTANTS_FILE); | ||
| var fileNames = ["urlparser.js"]; | ||
| fileNames.forEach(function(fileName){ | ||
| var src = fs.readFileSync("./src/" + fileName, "utf8"); | ||
| src = astPasses.removeComments(src, fileName); | ||
| src = astPasses.expandConstants(src, fileName); | ||
| src = getLicense() + src; | ||
| writeFile("./js/" + fileName, src); | ||
| }); | ||
| }); | ||
| grunt.registerTask( "testrun", function() { | ||
@@ -189,5 +125,5 @@ var fs = require("fs"); | ||
| grunt.registerTask( "test", ["jshint", "build", "testrun"] ); | ||
| grunt.registerTask( "default", ["jshint", "build"] ); | ||
| grunt.registerTask( "test", ["jshint", "testrun"] ); | ||
| grunt.registerTask( "default", ["jshint"] ); | ||
| }; |
+3
-3
@@ -1,2 +0,2 @@ | ||
| Copyright (c) 2013 Petka Antonov | ||
| Copyright (c) 2014 Petka Antonov | ||
@@ -8,3 +8,3 @@ Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions:</p> | ||
| furnished to do so, subject to the following conditions: | ||
@@ -20,2 +20,2 @@ The above copyright notice and this permission notice shall be included in | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| THE SOFTWARE. | ||
| THE SOFTWARE. |
+1
-1
| { | ||
| "name": "fast-url-parser", | ||
| "description": "Extremely fast implementation of node core url library", | ||
| "version": "1.0.2-0", | ||
| "version": "1.0.3-0", | ||
| "keywords": [ | ||
@@ -6,0 +6,0 @@ "fast", |
+52
-0
@@ -0,1 +1,29 @@ | ||
| #Introduction | ||
| Fast implementation of an url parser for node.js. | ||
| #Quick start | ||
| npm install fast-url-parser | ||
| ```js | ||
| var url = require("fast-url-parser"); | ||
| ``` | ||
| #API | ||
| This module has exactly the same API and semantics as the `require("url");`- module that comes with node. | ||
| See [Node.JS URL API documentation](http://nodejs.org/docs/latest/api/url.html). | ||
| If in your application you may want all modules use this parser automatically, you can do so by inserting this line at the beginning of your application: | ||
| ```js | ||
| require("fast-url-parser").replace(); | ||
| ``` | ||
| Anything that now calls `require("url")` will instead get an instance of this module instead of the url parser that comes with node core. | ||
| #Performance | ||
| Petka Antonov@PETKAANTONOV-PC ~/urlparser (master) | ||
@@ -18,1 +46,25 @@ $ node ./benchmark/urlparser.js | ||
| misc/url.js resolve("./foo/bar?baz"): 6968.4 | ||
| #License | ||
| MIT License: | ||
| Copyright (c) 2014 Petka Antonov | ||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
| The above copyright notice and this permission notice shall be included in | ||
| all copies or substantial portions of the Software. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| THE SOFTWARE. |
-918
| /** | ||
| * Copyright (c) 2013 Petka Antonov | ||
| * | ||
| * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| * of this software and associated documentation files (the "Software"), to deal | ||
| * in the Software without restriction, including without limitation the rights | ||
| * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| * copies of the Software, and to permit persons to whom the Software is | ||
| * furnished to do so, subject to the following conditions:</p> | ||
| * | ||
| * The above copyright notice and this permission notice shall be included in | ||
| * all copies or substantial portions of the Software. | ||
| * | ||
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| * THE SOFTWARE. | ||
| */ | ||
| "use strict"; | ||
| function Url() { | ||
| this._protocol = null; | ||
| this._href = ""; | ||
| this._port = -1; | ||
| this._query = null; | ||
| this.auth = null; | ||
| this.slashes = null; | ||
| this.host = null; | ||
| this.hostname = null; | ||
| this.hash = null; | ||
| this.search = null; | ||
| this.pathname = null; | ||
| this._prependSlash = false; | ||
| } | ||
| var querystring = require("querystring"); | ||
| Url.prototype.parse = | ||
| function Url$parse(str, parseQueryString, hostDenotesSlash) { | ||
| if (typeof str !== "string") { | ||
| throw new TypeError("Parameter 'url' must be a string, not " + | ||
| typeof str); | ||
| } | ||
| var start = 0; | ||
| var end = str.length - 1; | ||
| while (str.charCodeAt(start) <= 32) start++; | ||
| while (str.charCodeAt(end) <= 32) end--; | ||
| start = this._parseProtocol(str, start, end); | ||
| if (this._protocol !== "javascript") { | ||
| start = this._parseHost(str, start, end, hostDenotesSlash); | ||
| var proto = this._protocol; | ||
| if (!this.hostname && | ||
| (this.slashes || (proto && !slashProtocols[proto]))) { | ||
| this.hostname = this.host = ""; | ||
| } | ||
| } | ||
| if (start <= end) { | ||
| var ch = str.charCodeAt(start); | ||
| if (ch === 47) { | ||
| this._parsePath(str, start, end); | ||
| } | ||
| else if (ch === 63) { | ||
| this._parseQuery(str, start, end); | ||
| } | ||
| else if (ch === 35) { | ||
| this._parseHash(str, start, end); | ||
| } | ||
| else if (this._protocol !== "javascript") { | ||
| this._parsePath(str, start, end); | ||
| } | ||
| else { this.pathname = str.slice(start, end + 1 ); | ||
| } | ||
| } | ||
| if (!this.pathname && this.hostname && | ||
| this._slashProtocols[this._protocol]) { | ||
| this.pathname = "/"; | ||
| } | ||
| if (parseQueryString) { | ||
| var search = this.search; | ||
| if (search == null) { | ||
| search = this.search = ""; | ||
| } | ||
| if (search.charCodeAt(0) === 63) { | ||
| search = search.slice(1); | ||
| } | ||
| this.query = querystring.parse(search); | ||
| } | ||
| }; | ||
| Url.prototype.resolve = function Url$resolve(relative) { | ||
| return this.resolveObject(Url.parse(relative, false, true)).format(); | ||
| }; | ||
| Url.prototype.format = function Url$format() { | ||
| var auth = this.auth || ""; | ||
| if (auth) { | ||
| auth = encodeURIComponent(auth); | ||
| auth = auth.replace(/%3A/i, ":"); | ||
| auth += "@"; | ||
| } | ||
| var protocol = this.protocol || ""; | ||
| var pathname = this.pathname || ""; | ||
| var hash = this.hash || ""; | ||
| var search = this.search || ""; | ||
| var query = ""; | ||
| var hostname = this.hostname || ""; | ||
| var port = this.port || ""; | ||
| var host = false; | ||
| var scheme = ""; | ||
| var q = this.query; | ||
| if (q && typeof q === "object") { | ||
| query = querystring.stringify(q); | ||
| } | ||
| if (!search) { | ||
| search = query ? "?" + query : ""; | ||
| } | ||
| if (protocol && protocol.charCodeAt(protocol.length - 1) !== 58) | ||
| protocol += ":"; | ||
| if (this.host) { | ||
| host = auth + this.host; | ||
| } | ||
| else if (hostname) { | ||
| var ip6 = hostname.indexOf(":") > -1; | ||
| if (ip6) hostname = "[" + hostname + "]"; | ||
| host = auth + hostname + (port ? ":" + port : ""); | ||
| } | ||
| var slashes = this.slashes || | ||
| ((!protocol || | ||
| slashProtocols[protocol]) && host !== false); | ||
| if (protocol) scheme = protocol + (slashes ? "//" : ""); | ||
| else if (slashes && auth) scheme = "//"; | ||
| if (slashes && pathname && pathname.charCodeAt(0) !== 47) { | ||
| pathname = "/" + pathname; | ||
| } | ||
| else if (!slashes && pathname === "/") { | ||
| pathname = ""; | ||
| } | ||
| if (search && search.charCodeAt(0) !== 63) | ||
| search = "?" + search; | ||
| if (hash && hash.charCodeAt(0) !== 35) | ||
| hash = "#" + hash; | ||
| pathname = escapePathName(pathname); | ||
| search = escapeSearch(search); | ||
| return scheme + (host === false ? "" : host) + pathname + search + hash; | ||
| }; | ||
| Url.prototype.resolveObject = function Url$resolveObject(relative) { | ||
| if (typeof relative === "string") | ||
| relative = Url.parse(relative, false, true); | ||
| var result = this._clone(); | ||
| result.hash = relative.hash; | ||
| if (!relative.href) { | ||
| result._href = ""; | ||
| return result; | ||
| } | ||
| if (relative.slashes && !relative._protocol) { | ||
| relative._copyPropsTo(result, true); | ||
| if (slashProtocols[result._protocol] && | ||
| result.hostname && !result.pathname) { | ||
| result.pathname = "/"; | ||
| } | ||
| result._href = ""; | ||
| return result; | ||
| } | ||
| if (relative._protocol && relative._protocol !== result._protocol) { | ||
| if (!slashProtocols[relative._protocol]) { | ||
| relative._copyPropsTo(result, false); | ||
| result._href = ""; | ||
| return result; | ||
| } | ||
| result._protocol = relative._protocol; | ||
| if (!relative.host && relative._protocol !== "javascript") { | ||
| var relPath = (relative.pathname || "").split("/"); | ||
| while (relPath.length && !(relative.host = relPath.shift())); | ||
| if (!relative.host) relative.host = ""; | ||
| if (!relative.hostname) relative.hostname = ""; | ||
| if (relPath[0] !== "") relPath.unshift(""); | ||
| if (relPath.length < 2) relPath.unshift(""); | ||
| result.pathname = relPath.join("/"); | ||
| } else { | ||
| result.pathname = relative.pathname; | ||
| } | ||
| result.search = relative.search; | ||
| result.host = relative.host || ""; | ||
| result.auth = relative.auth; | ||
| result.hostname = relative.hostname || relative.host; | ||
| result._port = relative._port; | ||
| result.slashes = result.slashes || relative.slashes; | ||
| result._href = ""; | ||
| return result; | ||
| } | ||
| var isSourceAbs = | ||
| (result.pathname && result.pathname.charCodeAt(0) === 47); | ||
| var isRelAbs = ( | ||
| relative.host || | ||
| relative.pathname && relative.pathname.charCodeAt(0) === 47 | ||
| ); | ||
| var mustEndAbs = (isRelAbs || isSourceAbs || | ||
| (result.host && relative.pathname)); | ||
| var removeAllDots = mustEndAbs; | ||
| var srcPath = result.pathname && result.pathname.split("/") || []; | ||
| var relPath = relative.pathname && relative.pathname.split("/") || []; | ||
| var psychotic = result._protocol && !slashProtocols[result._protocol]; | ||
| if (psychotic) { | ||
| result.hostname = ""; | ||
| result._port = -1; | ||
| if (result.host) { | ||
| if (srcPath[0] === "") srcPath[0] = result.host; | ||
| else srcPath.unshift(result.host); | ||
| } | ||
| result.host = ""; | ||
| if (relative._protocol) { | ||
| relative.hostname = ""; | ||
| relative._port = -1; | ||
| if (relative.host) { | ||
| if (relPath[0] === "") relPath[0] = relative.host; | ||
| else relPath.unshift(relative.host); | ||
| } | ||
| relative.host = ""; | ||
| } | ||
| mustEndAbs = mustEndAbs && (relPath[0] === "" || srcPath[0] === ""); | ||
| } | ||
| if (isRelAbs) { | ||
| result.host = relative.host ? | ||
| relative.host : result.host; | ||
| result.hostname = relative.hostname ? | ||
| relative.hostname : result.hostname; | ||
| result.search = relative.search; | ||
| srcPath = relPath; | ||
| } else if (relPath.length) { | ||
| if (!srcPath) srcPath = []; | ||
| srcPath.pop(); | ||
| srcPath = srcPath.concat(relPath); | ||
| result.search = relative.search; | ||
| } else if (relative.search) { | ||
| if (psychotic) { | ||
| result.hostname = result.host = srcPath.shift(); | ||
| var authInHost = result.host && result.host.indexOf("@") > 0 ? | ||
| result.host.split("@") : false; | ||
| if (authInHost) { | ||
| result.auth = authInHost.shift(); | ||
| result.host = result.hostname = authInHost.shift(); | ||
| } | ||
| } | ||
| result.search = relative.search; | ||
| result._href = ""; | ||
| return result; | ||
| } | ||
| if (!srcPath.length) { | ||
| result.pathname = null; | ||
| result._href = ""; | ||
| return result; | ||
| } | ||
| var last = srcPath.slice(-1)[0]; | ||
| var hasTrailingSlash = ( | ||
| (result.host || relative.host) && (last === "." || last === "..") || | ||
| last === ""); | ||
| var up = 0; | ||
| for (var i = srcPath.length; i >= 0; i--) { | ||
| last = srcPath[i]; | ||
| if (last == ".") { | ||
| srcPath.splice(i, 1); | ||
| } else if (last === "..") { | ||
| srcPath.splice(i, 1); | ||
| up++; | ||
| } else if (up) { | ||
| srcPath.splice(i, 1); | ||
| up--; | ||
| } | ||
| } | ||
| if (!mustEndAbs && !removeAllDots) { | ||
| for (; up--; up) { | ||
| srcPath.unshift(".."); | ||
| } | ||
| } | ||
| if (mustEndAbs && srcPath[0] !== "" && | ||
| (!srcPath[0] || srcPath[0].charCodeAt(0) !== 47)) { | ||
| srcPath.unshift(""); | ||
| } | ||
| if (hasTrailingSlash && (srcPath.join("/").substr(-1) !== "/")) { | ||
| srcPath.push(""); | ||
| } | ||
| var isAbsolute = srcPath[0] === "" || | ||
| (srcPath[0] && srcPath[0].charCodeAt(0) === 47); | ||
| if (psychotic) { | ||
| result.hostname = result.host = isAbsolute ? "" : | ||
| srcPath.length ? srcPath.shift() : ""; | ||
| var authInHost = result.host && result.host.indexOf("@") > 0 ? | ||
| result.host.split("@") : false; | ||
| if (authInHost) { | ||
| result.auth = authInHost.shift(); | ||
| result.host = result.hostname = authInHost.shift(); | ||
| } | ||
| } | ||
| mustEndAbs = mustEndAbs || (result.host && srcPath.length); | ||
| if (mustEndAbs && !isAbsolute) { | ||
| srcPath.unshift(""); | ||
| } | ||
| result.pathname = srcPath.length === 0 ? null : srcPath.join("/"); | ||
| result.auth = relative.auth || result.auth; | ||
| result.slashes = result.slashes || relative.slashes; | ||
| result._href = ""; | ||
| return result; | ||
| }; | ||
| var punycode = require("punycode"); | ||
| Url.prototype._hostIdna = function Url$_hostIdna(hostname) { | ||
| var domainArray = hostname.split("."); | ||
| var newOut = []; | ||
| for (var i = 0; i < domainArray.length; ++i) { | ||
| var s = domainArray[i]; | ||
| newOut.push(s.match(/[^A-Za-z0-9_-]/) ? | ||
| "xn--" + punycode.encode(s) : s); | ||
| } | ||
| return newOut.join("."); | ||
| }; | ||
| var escapePathName = Url.prototype._escapePathName = | ||
| function Url$_escapePathName(pathname) { | ||
| if (!containsCharacter2(pathname, 35, 63)) return pathname; | ||
| return _escapePath(pathname); | ||
| }; | ||
| var escapeSearch = Url.prototype._escapeSearch = | ||
| function Url$_escapeSearch(search) { | ||
| if (!containsCharacter2(search, 35, -1)) return search; | ||
| return _escapeSearch(search); | ||
| }; | ||
| Url.prototype._parseProtocol = function Url$_parseProtocol(str, start, end) { | ||
| var doLowerCase = false; | ||
| var protocolCharacters = this._protocolCharacters; | ||
| for (var i = start; i <= end; ++i) { | ||
| var ch = str.charCodeAt(i); | ||
| if (ch === 58) { | ||
| var protocol = str.slice(start, i); | ||
| if (doLowerCase) protocol = protocol.toLowerCase(); | ||
| this._protocol = protocol; | ||
| return i + 1; | ||
| } | ||
| else if (protocolCharacters[ch] === 1) { | ||
| if (ch < 97) | ||
| doLowerCase = true; | ||
| } | ||
| else { | ||
| return start; | ||
| } | ||
| } | ||
| return start; | ||
| }; | ||
| Url.prototype._parseAuth = function Url$_parseAuth(str, start, end, decode) { | ||
| var auth = str.slice(start, end + 1); | ||
| if (decode) { | ||
| auth = decodeURIComponent(auth); | ||
| } | ||
| this.auth = auth; | ||
| }; | ||
| Url.prototype._parsePort = function Url$_parsePort(str, start, end) { | ||
| var port = 0; | ||
| var hadChars = false; | ||
| for (var i = start; i <= end; ++i) { | ||
| var ch = str.charCodeAt(i); | ||
| if (48 <= ch && ch <= 57) { | ||
| port = (10 * port) + (ch - 48); | ||
| hadChars = true; | ||
| } | ||
| else break; | ||
| } | ||
| if (port === 0 && !hadChars) { | ||
| return 0; | ||
| } | ||
| this._port = port; | ||
| return i - start; | ||
| }; | ||
| Url.prototype._parseHost = | ||
| function Url$_parseHost(str, start, end, slashesDenoteHost) { | ||
| var hostEndingCharacters = this._hostEndingCharacters; | ||
| if (str.charCodeAt(start) === 47 && | ||
| str.charCodeAt(start + 1) === 47) { | ||
| this.slashes = true; | ||
| if (start === 0) { | ||
| if (end < 2) return start; | ||
| var hasAuth = | ||
| containsCharacter(str, 64, 2, hostEndingCharacters); | ||
| if (!hasAuth && !slashesDenoteHost) { | ||
| return start; | ||
| } | ||
| } | ||
| start += 2; | ||
| } | ||
| else if (!this._protocol || | ||
| slashProtocols[this._protocol] | ||
| ) { | ||
| return start; | ||
| } | ||
| var doLowerCase = false; | ||
| var idna = false; | ||
| var hostNameStart = start; | ||
| var hostNameEnd = end; | ||
| var lastCh = -1; | ||
| var portLength = 0; | ||
| var charsAfterDot = 0; | ||
| var authNeedsDecoding = false; | ||
| var j = -1; | ||
| for (var i = start; i <= end; ++i) { | ||
| var ch = str.charCodeAt(i); | ||
| if (ch === 64) { | ||
| j = i; | ||
| } | ||
| else if (ch === 37) { | ||
| authNeedsDecoding = true; | ||
| } | ||
| else if (hostEndingCharacters[ch] === 1) { | ||
| break; | ||
| } | ||
| } | ||
| if (j > -1) { | ||
| this._parseAuth(str, start, j - 1, authNeedsDecoding); | ||
| start = hostNameStart = j + 1; | ||
| } | ||
| if (str.charCodeAt(start) === 91) { | ||
| for (var i = start + 1; i <= end; ++i) { | ||
| var ch = str.charCodeAt(i); | ||
| if (ch === 93) { | ||
| if (str.charCodeAt(i + 1) === 58) { | ||
| portLength = this._parsePort(str, i + 2, end) + 1; | ||
| } | ||
| var hostname = str.slice(start + 1, i).toLowerCase(); | ||
| this.hostname = hostname; | ||
| this.host = this._port > 0 | ||
| ? "[" + hostname + "]:" + this._port | ||
| : "[" + hostname + "]"; | ||
| this.pathname = "/"; | ||
| return i + portLength + 1; | ||
| } | ||
| } | ||
| return start; | ||
| } | ||
| for (var i = start; i <= end; ++i) { | ||
| if (charsAfterDot > 62) { | ||
| this.hostname = this.host = str.slice(start, i); | ||
| return i; | ||
| } | ||
| var ch = str.charCodeAt(i); | ||
| if (ch === 58) { | ||
| portLength = this._parsePort(str, i + 1, end) + 1; | ||
| hostNameEnd = i - 1; | ||
| break; | ||
| } | ||
| else if (ch < 97) { | ||
| if (ch === 46) { | ||
| charsAfterDot = -1; | ||
| } | ||
| else if (65 <= ch && ch <= 90) { | ||
| doLowerCase = true; | ||
| } | ||
| else if (!(ch === 45 || ch === 95 || | ||
| (48 <= ch && ch <= 57))) { | ||
| if (hostEndingCharacters[ch] === 0 && | ||
| this._noPrependSlashHostEnders[ch] === 0) { | ||
| this._prependSlash = true; | ||
| } | ||
| hostNameEnd = i - 1; | ||
| break; | ||
| } | ||
| } | ||
| else if (ch >= 0x7B) { | ||
| if (ch <= 0x7E) { | ||
| if (this._noPrependSlashHostEnders[ch] === 0) { | ||
| this._prependSlash = true; | ||
| } | ||
| hostNameEnd = i - 1; | ||
| break; | ||
| } | ||
| idna = true; | ||
| } | ||
| lastCh = ch; | ||
| charsAfterDot++; | ||
| } | ||
| if (hostNameEnd + 1 !== start && | ||
| hostNameEnd - hostNameStart <= 256) { | ||
| var hostname = str.slice(hostNameStart, hostNameEnd + 1); | ||
| if (doLowerCase) hostname = hostname.toLowerCase(); | ||
| if (idna) hostname = this._hostIdna(hostname); | ||
| this.hostname = hostname; | ||
| this.host = this._port > 0 ? hostname + ":" + this._port : hostname; | ||
| } | ||
| return hostNameEnd + 1 + portLength; | ||
| }; | ||
| Url.prototype._copyPropsTo = function Url$_copyPropsTo(input, noProtocol) { | ||
| if (!noProtocol) { | ||
| input._protocol = this._protocol; | ||
| } | ||
| input._href = this._href; | ||
| input._port = this._port; | ||
| input._prependSlash = this._prependSlash; | ||
| input.auth = this.auth; | ||
| input.slashes = this.slashes; | ||
| input.host = this.host; | ||
| input.hostname = this.hostname; | ||
| input.hash = this.hash; | ||
| input.search = this.search; | ||
| input.pathname = this.pathname; | ||
| }; | ||
| Url.prototype._clone = function Url$_clone() { | ||
| var ret = new Url(); | ||
| ret._protocol = this._protocol; | ||
| ret._href = this._href; | ||
| ret._port = this._port; | ||
| ret._prependSlash = this._prependSlash; | ||
| ret.auth = this.auth; | ||
| ret.slashes = this.slashes; | ||
| ret.host = this.host; | ||
| ret.hostname = this.hostname; | ||
| ret.hash = this.hash; | ||
| ret.search = this.search; | ||
| ret.pathname = this.pathname; | ||
| return ret; | ||
| }; | ||
| Url.prototype._getComponentEscaped = | ||
| function Url$_getComponentEscaped(str, start, end) { | ||
| var cur = start; | ||
| var i = start; | ||
| var ret = ""; | ||
| var autoEscapeMap = this._autoEscapeMap; | ||
| for (; i <= end; ++i) { | ||
| var ch = str.charCodeAt(i); | ||
| var escaped = autoEscapeMap[ch]; | ||
| if (escaped !== "") { | ||
| if (cur < i) ret += str.slice(cur, i); | ||
| ret += escaped; | ||
| cur = i + 1; | ||
| } | ||
| } | ||
| if (cur < i + 1) ret += str.slice(cur, i); | ||
| return ret; | ||
| }; | ||
| Url.prototype._parsePath = | ||
| function Url$_parsePath(str, start, end) { | ||
| var pathStart = start; | ||
| var pathEnd = end; | ||
| var escape = false; | ||
| var autoEscapeCharacters = this._autoEscapeCharacters; | ||
| for (var i = start; i <= end; ++i) { | ||
| var ch = str.charCodeAt(i); | ||
| if (ch === 35) { | ||
| this._parseHash(str, i, end); | ||
| pathEnd = i - 1; | ||
| break; | ||
| } | ||
| else if (ch === 63) { | ||
| this._parseQuery(str, i, end); | ||
| pathEnd = i - 1; | ||
| break; | ||
| } | ||
| else if (!escape && autoEscapeCharacters[ch] === 1) { | ||
| escape = true; | ||
| } | ||
| } | ||
| if (pathStart > pathEnd) { | ||
| this.pathname = "/"; | ||
| return; | ||
| } | ||
| var path; | ||
| if (escape) { | ||
| path = this._getComponentEscaped(str, pathStart, pathEnd); | ||
| } | ||
| else { | ||
| path = str.slice(pathStart, pathEnd + 1); | ||
| } | ||
| this.pathname = this._prependSlash ? "/" + path : path; | ||
| }; | ||
| Url.prototype._parseQuery = function Url$_parseQuery(str, start, end) { | ||
| var queryStart = start; | ||
| var queryEnd = end; | ||
| var escape = false; | ||
| var autoEscapeCharacters = this._autoEscapeCharacters; | ||
| for (var i = start; i <= end; ++i) { | ||
| var ch = str.charCodeAt(i); | ||
| if (ch === 35) { | ||
| this._parseHash(str, i, end); | ||
| queryEnd = i - 1; | ||
| break; | ||
| } | ||
| else if (!escape && autoEscapeCharacters[ch] === 1) { | ||
| escape = true; | ||
| } | ||
| } | ||
| if (queryStart > queryEnd) { | ||
| this.search = ""; | ||
| return; | ||
| } | ||
| var query; | ||
| if (escape) { | ||
| query = this._getComponentEscaped(str, queryStart, queryEnd); | ||
| } | ||
| else { | ||
| query = str.slice(queryStart, queryEnd + 1); | ||
| } | ||
| this.search = query; | ||
| }; | ||
| Url.prototype._parseHash = function Url$_parseHash(str, start, end) { | ||
| if (start > end) { | ||
| this.hash = ""; | ||
| return; | ||
| } | ||
| this.hash = this._getComponentEscaped(str, start, end); | ||
| }; | ||
| Object.defineProperty(Url.prototype, "port", { | ||
| get: function() { | ||
| if (this._port >= 0) { | ||
| return ("" + this._port); | ||
| } | ||
| return null; | ||
| }, | ||
| set: function(v) { | ||
| this._port = parseInt(v, 10); | ||
| } | ||
| }); | ||
| Object.defineProperty(Url.prototype, "query", { | ||
| get: function() { | ||
| var query = this._query; | ||
| if (query != null) { | ||
| return query; | ||
| } | ||
| var search = this.search; | ||
| if (search) { | ||
| if (search.charCodeAt(0) === 63) { | ||
| search = search.slice(1); | ||
| } | ||
| if (search !== "") { | ||
| this._query = search; | ||
| return search; | ||
| } | ||
| } | ||
| return search; | ||
| }, | ||
| set: function(v) { | ||
| this._query = v; | ||
| } | ||
| }); | ||
| Object.defineProperty(Url.prototype, "path", { | ||
| get: function() { | ||
| var p = this.pathname || ""; | ||
| var s = this.search || ""; | ||
| if (p || s) { | ||
| return p + s; | ||
| } | ||
| return (p == null && s) ? ("/" + s) : null; | ||
| }, | ||
| set: function() {} | ||
| }); | ||
| Object.defineProperty(Url.prototype, "protocol", { | ||
| get: function() { | ||
| var proto = this._protocol; | ||
| return proto ? proto + ":" : proto; | ||
| }, | ||
| set: function(v) { | ||
| var end = v.length - 1; | ||
| if (v.charCodeAt(end) === 58) { | ||
| this._protocol = v.slice(0, end); | ||
| } | ||
| else { | ||
| this._protocol = v; | ||
| } | ||
| } | ||
| }); | ||
| Object.defineProperty(Url.prototype, "href", { | ||
| get: function() { | ||
| var href = this._href; | ||
| if (!href) { | ||
| href = this._href = this.format(); | ||
| } | ||
| return href; | ||
| }, | ||
| set: function(v) { | ||
| this._href = v; | ||
| } | ||
| }); | ||
| Url.parse = function Url$Parse(str, parseQueryString, hostDenotesSlash) { | ||
| if (str instanceof Url) return str; | ||
| var ret = new Url(); | ||
| ret.parse(str, !!parseQueryString, !!hostDenotesSlash); | ||
| return ret; | ||
| }; | ||
| Url.format = function Url$Format(obj) { | ||
| if (typeof obj === "string") { | ||
| obj = Url.parse(obj); | ||
| } | ||
| if (!(obj instanceof Url)) { | ||
| return Url.prototype.format.call(obj); | ||
| } | ||
| return obj.format(); | ||
| }; | ||
| Url.resolve = function Url$Resolve(source, relative) { | ||
| return Url.parse(source, false, true).resolve(relative); | ||
| }; | ||
| Url.resolveObject = function Url$ResolveObject(source, relative) { | ||
| if (!source) return relative; | ||
| return Url.parse(source, false, true).resolveObject(relative); | ||
| }; | ||
| function _escapePath(pathname) { | ||
| return pathname.replace(/[?#]/g, function(match) { | ||
| return encodeURIComponent(match); | ||
| }); | ||
| } | ||
| function _escapeSearch(search) { | ||
| return search.replace(/#/g, function(match) { | ||
| return encodeURIComponent(match); | ||
| }); | ||
| } | ||
| function containsCharacter(string, char1, fromIndex, stopCharacterTable) { | ||
| var len = string.length; | ||
| for (var i = fromIndex; i < len; ++i) { | ||
| var ch = string.charCodeAt(i); | ||
| if (ch === char1) { | ||
| return true; | ||
| } | ||
| else if (stopCharacterTable[ch] === 1) { | ||
| return false; | ||
| } | ||
| } | ||
| return false; | ||
| } | ||
| function containsCharacter2(string, char1, char2) { | ||
| for (var i = 0, len = string.length; i < len; ++i) { | ||
| var ch = string.charCodeAt(i); | ||
| if (ch === char1 || ch === char2) return true; | ||
| } | ||
| return false; | ||
| } | ||
| function makeAsciiTable(spec) { | ||
| var ret = new Uint8Array(128); | ||
| spec.forEach(function(item){ | ||
| if (typeof item === "number") { | ||
| ret[item] = 1; | ||
| } | ||
| else { | ||
| var start = item[0]; | ||
| var end = item[1]; | ||
| for (var j = start; j <= end; ++j) { | ||
| ret[j] = 1; | ||
| } | ||
| } | ||
| }); | ||
| return ret; | ||
| } | ||
| var autoEscape = ["<", ">", "\"", "`", " ", "\r", "\n", | ||
| "\t", "{", "}", "|", "\\", "^", "`", "'"]; | ||
| var autoEscapeMap = new Array(128); | ||
| for (var i = 0, len = autoEscapeMap.length; i < len; ++i) { | ||
| autoEscapeMap[i] = ""; | ||
| } | ||
| for (var i = 0, len = autoEscape.length; i < len; ++i) { | ||
| var c = autoEscape[i]; | ||
| var esc = encodeURIComponent(c); | ||
| if (esc === c) { | ||
| esc = escape(c); | ||
| } | ||
| autoEscapeMap[c.charCodeAt(0)] = esc; | ||
| } | ||
| var slashProtocols = Url.prototype._slashProtocols = { | ||
| http: true, | ||
| https: true, | ||
| gopher: true, | ||
| file: true, | ||
| ftp: true, | ||
| "http:": true, | ||
| "https:": true, | ||
| "gopher:": true, | ||
| "file:": true, | ||
| "ftp:": true | ||
| }; | ||
| function f(){} | ||
| f.prototype = slashProtocols; | ||
| Url.prototype._protocolCharacters = makeAsciiTable([ | ||
| [97, 122], | ||
| [65, 90], | ||
| 46, 43, 45 | ||
| ]); | ||
| Url.prototype._hostEndingCharacters = makeAsciiTable([ | ||
| 35, 63, 47 | ||
| ]); | ||
| Url.prototype._autoEscapeCharacters = makeAsciiTable( | ||
| autoEscape.map(function(v) { | ||
| return v.charCodeAt(0); | ||
| }) | ||
| ); | ||
| Url.prototype._noPrependSlashHostEnders = makeAsciiTable( | ||
| [ | ||
| "<", ">", "'", "`", " ", "\r", | ||
| "\n", "\t", "{", "}", "|", "\\", | ||
| "^", "`", "\"", "%", ";" | ||
| ].map(function(v) { | ||
| return v.charCodeAt(0); | ||
| }) | ||
| ); | ||
| Url.prototype._autoEscapeMap = autoEscapeMap; | ||
| module.exports = Url; |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
70
288.89%1
-80%8602
-74.54%5
-16.67%106
-88.9%1
Infinity%