Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Refactor the codebase to make it more secure
  • Loading branch information
IonicaBizau committed Jun 27, 2022
1 parent 3795a3c commit f9ad885
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 147 deletions.
140 changes: 38 additions & 102 deletions lib/index.js
@@ -1,8 +1,4 @@
// Dependencies
const protocols = require("protocols")
, isSsh = require("is-ssh")
, qs = require("query-string")
;

/**
* parsePath
Expand All @@ -25,110 +21,50 @@ const protocols = require("protocols")
* - `query` (Object): The url querystring, parsed as object.
*/
function parsePath(url) {
url = (url || "").trim().replace(/\r?\n|\r/gm, "")
var output = {
protocols: protocols(url)
, protocol: null
, port: null
, resource: ""
, user: ""
, pathname: ""
, hash: ""
, search: ""
, href: url
, query: Object.create(null)
}
, protocolIndex = url.indexOf("://")
, resourceIndex = -1
, splits = null
, parts = null
;

if (url.startsWith(".")) {
if (url.startsWith("./")) {
url = url.substring(2);
}
output.pathname = url;
output.protocol = "file";
const output = {
protocols: []
, protocol: null
, port: null
, resource: ""
, user: ""
, password: ""
, pathname: ""
, hash: ""
, search: ""
, href: url
, query: {}
}

const firstChar = url.charAt(1)
if (!output.protocol) {
try {
const parsed = new URL(url)
output.protocols = protocols(parsed)
output.protocol = output.protocols[0]
if (!output.protocol) {
if (isSsh(url)) {
output.protocol = "ssh"
} else if (firstChar === "/" || firstChar === "~") {
url = url.substring(2)
output.protocol = "file"
} else {
output.protocol = "file"
}
}
}

if (protocolIndex !== -1) {
url = url.substring(protocolIndex + 3);
}

parts = url.split(/\/|\\/);
if (output.protocol !== "file") {
output.resource = parts.shift();
} else {
output.resource = "";
}

// user@domain
splits = output.resource.split("@");
if (splits.length === 2) {
output.user = splits[0];
output.resource = splits[1];
}


// domain.com:port
splits = output.resource.split(":");
if (splits.length === 2) {
output.resource = splits[0];
const port = splits[1];
if (port) {
output.port = Number(port);
if (isNaN(output.port) || port.match(/^\d+$/) === null) {
output.port = null;
parts.unshift(port);
}
} else {
output.port = null
}
}

// Remove empty elements
parts = parts.filter(Boolean);

// Stringify the pathname
if (output.protocol === "file") {
output.pathname = output.href
} else {
output.pathname = output.pathname || ((output.protocol !== "file" || output.href[0] === "/" ? "/" : "") + parts.join("/"));
}

// #some-hash
splits = output.pathname.split("#");
if (splits.length === 2) {
output.pathname = splits[0];
output.hash = splits[1];
}

// ?foo=bar
splits = output.pathname.split("?");
if (splits.length === 2) {
output.pathname = splits[0];
output.search = splits[1];
output.port = parsed.port
output.resource = parsed.host
output.user = parsed.username || ""
output.password = parsed.password || ""
output.pathname = parsed.pathname
output.hash = parsed.hash.slice(1)
output.search = parsed.search.slice(1)
output.href = parsed.href
output.query = Object.fromEntries(parsed.searchParams)
} catch (e) {
// TODO Maybe check if it is a valid local file path
// In any case, these will be parsed by higher
// level parsers such as parse-url, git-url-parse, git-up
output.protocols = ["file"]
output.protocol = output.protocols[0]
output.port = ""
output.resource = ""
output.user = ""
output.pathname = ""
output.hash = ""
output.search = ""
output.href = url
output.query = {}
}

output.query = qs.parse(output.search);
output.href = output.href.replace(/\/$/, "")
output.pathname = output.pathname.replace(/\/$/, "")
return output;
}

Expand Down
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -52,4 +52,4 @@
"bloggify.json",
"bloggify/"
]
}
}

0 comments on commit f9ad885

Please sign in to comment.