From b88c81df8f4c5168af454eaa4f92afa9349e4e13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionic=C4=83=20Biz=C4=83u?= Date: Wed, 3 Aug 2022 11:22:27 +0300 Subject: [PATCH] Throw if url is invalid. Add a length limit. --- lib/index.js | 20 +++++++++++++++++--- test/index.js | 42 ++++++++++++++++++++++++++++++++---------- 2 files changed, 49 insertions(+), 13 deletions(-) diff --git a/lib/index.js b/lib/index.js index b806431..fe5a052 100644 --- a/lib/index.js +++ b/lib/index.js @@ -32,18 +32,27 @@ import normalizeUrl from "normalize-url"; * - `search` (String): The url querystring value. * - `href` (String): The input url. * - `query` (Object): The url querystring, parsed as object. + * - `parse_failed` (Boolean): Whether the parsing failed or not. */ const parseUrl = (url, normalize = false) => { // Constants const GIT_RE = /(^(git@|http(s)?:\/\/)([\w\.\-@]+)(\/|:))(([\~,\.\w,\-,\_,\/]+)(.git){0,1}((\/){0,1}))/ - if (typeof url !== "string" || !url.trim()) { - const err = new Error("Invalid url.") + const throwErr = msg => { + const err = new Error(msg) err.subject_url = url throw err } + if (typeof url !== "string" || !url.trim()) { + throwErr("Invalid url.") + } + + if (url.length > parseUrl.MAX_INPUT_LENGTH) { + throwErr("Input exceeds maximum length. If needed, change the value of parseUrl.MAX_INPUT_LENGTH.") + } + if (normalize) { if (typeof normalize !== "object") { normalize = { @@ -56,7 +65,7 @@ const parseUrl = (url, normalize = false) => { const parsed = parsePath(url) // Potential git-ssh urls - if (parsed.protocol === "file") { + if (parsed.parse_failed) { const matched = parsed.href.match(GIT_RE) if (matched) { parsed.protocols = ["ssh"] @@ -65,10 +74,15 @@ const parseUrl = (url, normalize = false) => { parsed.host = matched[4] parsed.user = "git" parsed.pathname = `/${matched[6]}` + parsed.parse_failed = false + } else { + throwErr("URL parsing failed.") } } return parsed; } +parseUrl.MAX_INPUT_LENGTH = 2048 + export default parseUrl; diff --git a/test/index.js b/test/index.js index 1a50435..288c36c 100644 --- a/test/index.js +++ b/test/index.js @@ -17,6 +17,7 @@ const INPUTS = [ , hash: "" , search: "" , query: {} + , parse_failed: false } ] , [ @@ -32,6 +33,7 @@ const INPUTS = [ , hash: "" , search: "" , query: {} + , parse_failed: false } ] , [ @@ -47,6 +49,7 @@ const INPUTS = [ , hash: "some-hash?foo=bar" , search: "" , query: {} + , parse_failed: false } ] , [ @@ -62,6 +65,7 @@ const INPUTS = [ , hash: "" , search: "" , query: {} + , parse_failed: false } ] , [ @@ -77,6 +81,7 @@ const INPUTS = [ , hash: "" , search: "" , query: {} + , parse_failed: false } ] , [ @@ -92,6 +97,7 @@ const INPUTS = [ , hash: "" , search: "" , query: {} + , parse_failed: false } ] , [ @@ -107,22 +113,24 @@ const INPUTS = [ , hash: "http://a:1:1" , search: "" , query: {} + , parse_failed: false } ] , [ ["git@github.my-enterprise.com:my-org/my-repo.git", false], { protocols: [ 'ssh' ] - , protocol: 'ssh' - , port: '' - , resource: 'github.my-enterprise.com' - , host: 'github.my-enterprise.com' - , user: 'git' - , password: '' - , pathname: '/my-org/my-repo.git' - , hash: '' - , search: '' - , query: {} + , protocol: 'ssh' + , port: '' + , resource: 'github.my-enterprise.com' + , host: 'github.my-enterprise.com' + , user: 'git' + , password: '' + , pathname: '/my-org/my-repo.git' + , hash: '' + , search: '' + , query: {} + , parse_failed: false } ] , [ @@ -138,6 +146,7 @@ const INPUTS = [ , hash: "" , search: "" , query: {} + , parse_failed: false } ] ]; @@ -165,4 +174,17 @@ tester.describe("check urls", test => { parseUrl("") }).toThrow(/invalid url/i) }) + + test.should("throw if url is too long", () => { + parseUrl.MAX_INPUT_LENGTH = 10 + test.expect(() => { + parseUrl("https://domain.com/") + }).toThrow(/input exceeds maximum length/i) + }) + + test.should("throw if url is invalid", () => { + test.expect(() => { + parseUrl("foo") + }).toThrow(/url parsing failed/i) + }) });