diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index 8d4b904a4861f..29b52c4684851 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -603,11 +603,6 @@ bool AtomBrowserClient::CanCreateWindow( int opener_render_process_id = opener->GetProcess()->GetID(); - if (IsRendererSandboxed(opener_render_process_id)) { - *no_javascript_access = false; - return true; - } - if (RendererUsesNativeWindowOpen(opener_render_process_id)) { if (RendererDisablesPopups(opener_render_process_id)) { // without allowpopups attribute should return diff --git a/atom/browser/web_contents_preferences.cc b/atom/browser/web_contents_preferences.cc index b4399263d9096..4156b02d01ddc 100644 --- a/atom/browser/web_contents_preferences.cc +++ b/atom/browser/web_contents_preferences.cc @@ -147,6 +147,8 @@ WebContentsPreferences::WebContentsPreferences( #endif SetDefaultBoolIfUndefined(options::kOffscreen, false); + SetDefaults(); + // If this is a tag, and the embedder is offscreen-rendered, then // this WebContents is also offscreen-rendered. int guest_instance_id = 0; @@ -172,6 +174,12 @@ WebContentsPreferences::~WebContentsPreferences() { instances_.end()); } +void WebContentsPreferences::SetDefaults() { + if (IsEnabled(options::kSandbox)) { + SetBool(options::kNativeWindowOpen, true); + } +} + bool WebContentsPreferences::SetDefaultBoolIfUndefined( const base::StringPiece& key, bool val) { @@ -185,6 +193,10 @@ bool WebContentsPreferences::SetDefaultBoolIfUndefined( } } +void WebContentsPreferences::SetBool(const base::StringPiece& key, bool value) { + preference_.SetKey(key, base::Value(value)); +} + bool WebContentsPreferences::IsEnabled(const base::StringPiece& name, bool default_value) const { auto* current_value = @@ -197,6 +209,8 @@ bool WebContentsPreferences::IsEnabled(const base::StringPiece& name, void WebContentsPreferences::Merge(const base::DictionaryValue& extend) { if (preference_.is_dict()) static_cast(&preference_)->MergeDictionary(&extend); + + SetDefaults(); } void WebContentsPreferences::Clear() { diff --git a/atom/browser/web_contents_preferences.h b/atom/browser/web_contents_preferences.h index f635008021def..465acf4a1569a 100644 --- a/atom/browser/web_contents_preferences.h +++ b/atom/browser/web_contents_preferences.h @@ -36,6 +36,9 @@ class WebContentsPreferences const mate::Dictionary& web_preferences); ~WebContentsPreferences() override; + // Set WebPreferences defaults onto the JS object. + void SetDefaults(); + // A simple way to know whether a Boolean property is enabled. bool IsEnabled(const base::StringPiece& name, bool default_value = false) const; @@ -75,6 +78,9 @@ class WebContentsPreferences // Set preference value to given bool if user did not provide value bool SetDefaultBoolIfUndefined(const base::StringPiece& key, bool val); + // Set preference value to given bool + void SetBool(const base::StringPiece& key, bool value); + static std::vector instances_; content::WebContents* web_contents_; diff --git a/lib/browser/guest-view-manager.js b/lib/browser/guest-view-manager.js index 01673497ccbf8..b00c11b3cd6f3 100644 --- a/lib/browser/guest-view-manager.js +++ b/lib/browser/guest-view-manager.js @@ -112,7 +112,6 @@ const createGuest = function (embedder, params) { } this.loadURL(params.src, opts) } - guest.allowPopups = params.allowpopups embedder.emit('did-attach-webview', event, guest) }) @@ -207,6 +206,7 @@ const attachGuest = function (event, embedderFrameId, elementInstanceId, guestIn enableRemoteModule: params.enableremotemodule, plugins: params.plugins, zoomFactor: embedder.getZoomFactor(), + disablePopups: !params.allowpopups, webSecurity: !params.disablewebsecurity, enableBlinkFeatures: params.blinkfeatures, disableBlinkFeatures: params.disableblinkfeatures @@ -228,11 +228,6 @@ const attachGuest = function (event, embedderFrameId, elementInstanceId, guestIn webPreferences.preloadURL = params.preload } - // Return null from native window.open if allowpopups is unset - if (webPreferences.nativeWindowOpen === true && !params.allowpopups) { - webPreferences.disablePopups = true - } - // Security options that guest will always inherit from embedder const inheritedWebPreferences = new Map([ ['contextIsolation', true], diff --git a/lib/browser/guest-window-manager.js b/lib/browser/guest-window-manager.js index ee4b185594869..8c1eed868637f 100644 --- a/lib/browser/guest-window-manager.js +++ b/lib/browser/guest-window-manager.js @@ -244,7 +244,7 @@ ipcMainInternal.on('ELECTRON_GUEST_WINDOW_MANAGER_INTERNAL_WINDOW_OPEN', functio options = mergeBrowserWindowOptions(event.sender, options) event.sender.emit('new-window', event, url, frameName, disposition, options, additionalFeatures, referrer) const { newGuest } = event - if ((event.sender.isGuest() && !event.sender.allowPopups) || event.defaultPrevented) { + if ((event.sender.isGuest() && event.sender.getLastWebPreferences().disablePopups) || event.defaultPrevented) { if (newGuest != null) { if (options.webContents === newGuest.webContents) { // the webContents is not changed, so set defaultPrevented to false to diff --git a/spec/webview-spec.js b/spec/webview-spec.js index d04f12e0b706e..d656c3b8c4b41 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -546,20 +546,30 @@ describe(' tag', function () { }) describe('allowpopups attribute', () => { - it('can not open new window when not set', async () => { - const message = await startLoadingWebViewAndWaitForMessage(webview, { - src: `file://${fixtures}/pages/window-open-hide.html` - }) - expect(message).to.equal('null') - }) + const generateSpecs = (description, webpreferences = '') => { + describe(description, () => { + it('can not open new window when not set', async () => { + const message = await startLoadingWebViewAndWaitForMessage(webview, { + webpreferences, + src: `file://${fixtures}/pages/window-open-hide.html` + }) + expect(message).to.equal('null') + }) - it('can open new window when set', async () => { - const message = await startLoadingWebViewAndWaitForMessage(webview, { - allowpopups: 'on', - src: `file://${fixtures}/pages/window-open-hide.html` + it('can open new window when set', async () => { + const message = await startLoadingWebViewAndWaitForMessage(webview, { + webpreferences, + allowpopups: 'on', + src: `file://${fixtures}/pages/window-open-hide.html` + }) + expect(message).to.equal('window') + }) }) - expect(message).to.equal('window') - }) + } + + generateSpecs('without sandbox') + generateSpecs('with sandbox', 'sandbox=yes') + generateSpecs('with nativeWindowOpen', 'nativeWindowOpen=yes') }) describe('webpreferences attribute', () => {