diff --git a/js/lib/urlutil.js b/js/lib/urlutil.js index 1f6a6ff7c7..ef228cd6c2 100644 --- a/js/lib/urlutil.js +++ b/js/lib/urlutil.js @@ -6,8 +6,10 @@ // characters, then : with optional // const rscheme = /^(?:[a-z\u00a1-\uffff0-9-+]+)(?::(\/\/)?)(?!\d)/i -const defaultScheme = 'http://' +const httpScheme = 'http://' +const httpsScheme = 'https://' const fileScheme = 'file://' +const defaultScheme = httpScheme const os = require('os') const punycode = require('punycode') const urlParse = require('../../app/common/urlParse') @@ -87,10 +89,6 @@ const UrlUtil = { return (url.match(/\.(jpeg|jpg|gif|png|bmp)$/)) }, - isHttpAddress (url) { - return (url.match(/^https?:\/\/(.*)/)) - }, - /** * Checks if a string is not a URL. * @param {String} input The input value. @@ -133,7 +131,7 @@ const UrlUtil = { if (case4Reg.test(str)) { return !UrlUtil.canParseURL(str) } - if (scheme && (scheme !== 'file://')) { + if (scheme && (scheme !== fileScheme)) { return !caseDomain.test(str + '/') } str = UrlUtil.prependScheme(str) @@ -244,7 +242,7 @@ const UrlUtil = { * @returns {String} The view-source URL. */ getViewSourceUrlFromUrl: function (input) { - if (UrlUtil.isImageAddress(input) || !UrlUtil.isHttpAddress(input)) { + if (!UrlUtil.isHttpOrHttps(input) && !UrlUtil.isFileScheme(input) || UrlUtil.isImageAddress(input)) { return null } if (UrlUtil.isViewSourceUrl(input)) { @@ -381,11 +379,20 @@ const UrlUtil = { /** * Checks if URL is based on http protocol. - * @param {string} url The URL to get the hostPattern from - * @return {string} url The URL formmatted as an hostPattern + * @param {string} url - URL to check + * @return {boolean} */ isHttpOrHttps: function (url) { - return url.startsWith('https://') || url.startsWith('http://') + return url.startsWith(httpScheme) || url.startsWith(httpsScheme) + }, + + /** + * Checks if URL is based on file protocol. + * @param {string} url - URL to check + * @return {boolean} + */ + isFileScheme: function (url) { + return this.getScheme(url) === fileScheme }, /** diff --git a/test/tab-components/frameTest.js b/test/tab-components/frameTest.js index 602b3542b1..3dc3832368 100644 --- a/test/tab-components/frameTest.js +++ b/test/tab-components/frameTest.js @@ -208,6 +208,33 @@ describe('frame tests', function () { }) }) + describe('view source for file scheme', function () { + Brave.beforeAll(this) + + before(function * () { + this.url = Brave.fixtureUrl('viewSourceForFileScheme.html') + + this.webview1 = '.frameWrapper:nth-child(1) webview' + this.webview2 = '.frameWrapper:nth-child(2) webview' + + yield setup(this.app.client) + yield this.app.client + .tabByIndex(0) + .loadUrl(this.url) + .windowByUrl(Brave.browserWindowUrl) + .waitForExist('[data-test-id="tab"][data-frame-key="1"]') + .waitForExist(this.webview1) + }) + + it('should open in new tab', function * () { + yield this.app.client + .ipcSend(messages.SHORTCUT_ACTIVE_FRAME_VIEW_SOURCE) + .waitForTabCount(2) + .windowByUrl(Brave.browserWindowUrl) + .waitForExist(this.webview2) + }) + }) + describe('resource loading', function () { Brave.beforeAll(this) before(function * () { diff --git a/test/unit/lib/urlutilTest.js b/test/unit/lib/urlutilTest.js index 7c2d347468..4b7d17ac7c 100644 --- a/test/unit/lib/urlutilTest.js +++ b/test/unit/lib/urlutilTest.js @@ -301,4 +301,23 @@ describe('urlutil', function () { assert.equal(UrlUtil.isPotentialPhishingUrl(' BLOB:foo '), true) }) }) + + describe('isFileScheme', function () { + describe('returns true when input:', function () { + it('is an absolute file path with scheme', function () { + assert.equal(UrlUtil.isFileScheme('file:///file/path/to/file'), true); + }) + }) + describe('returns false when input:', function () { + it('is an absolute file path without scheme', function () { + assert.equal(UrlUtil.isFileScheme('/file/path/to/file'), false) + }) + it('is a URL', function () { + assert.equal(UrlUtil.isFileScheme('http://brave.com'), false) + }) + it('has custom protocol', function () { + assert.equal(UrlUtil.isFileScheme('brave://test'), false) + }) + }) + }) })