8000 Backport (1-7-x) - Set appropriate defaults for webview options by MarshallOfSound · Pull Request #12294 · electron/electron · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Backport (1-7-x) - Set appropriate defaults for webview options #12294

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions atom/browser/api/atom_api_web_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1721,6 +1721,14 @@ v8::Local<v8::Value> WebContents::GetWebPreferences(v8::Isolate* isolate) {
return mate::ConvertToV8(isolate, *web_preferences->web_preferences());
}

v8::Local<v8::Value> WebContents::GetLastWebPreferences(v8::Isolate* isolate) {
WebContentsPreferences* web_preferences =
WebContentsPreferences::FromWebContents(web_contents());
if (!web_preferences)
return v8::Null(isolate);
return mate::ConvertToV8(isolate, *web_preferences->last_web_preferences());
}

v8::Local<v8::Value> WebContents::GetOwnerBrowserWindow() {
if (owner_window())
return Window::From(isolate(), owner_window());
Expand Down Expand Up @@ -1851,6 +1859,7 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
.SetMethod("_getZoomFactor", &WebContents::GetZoomFactor)
.SetMethod("getType", &WebContents::GetType)
.SetMethod("getWebPreferences", &WebContents::GetWebPreferences)
.SetMethod("getLastWebPreferences", &WebContents::GetLastWebPreferences)
.SetMethod("getOwnerBrowserWindow", &WebContents::GetOwnerBrowserWindow)
.SetMethod("hasServiceWorker", &WebContents::HasServiceWorker)
.SetMethod("unregisterServiceWorker",
Expand Down
1 change: 1 addition & 0 deletions atom/browser/api/atom_api_web_contents.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ class WebContents : public mate::TrackableObject<WebContents>,

// Returns the web preferences of current WebContents.
v8::Local<v8::Value> GetWebPreferences(v8::Isolate* isolate);
v8::Local<v8::Value> GetLastWebPreferences(v8::Isolate* isolate);

// Returns the owner window.
v8::Local<v8::Value> GetOwnerBrowserWindow();
Expand Down
38 changes: 38 additions & 0 deletions atom/browser/web_contents_preferences.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,28 @@ WebContentsPreferences::WebContentsPreferences(
web_contents->SetUserData(UserDataKey(), this);

instances_.push_back(this);

// Set WebPreferences defaults onto the JS object
SetDefaultBoolIfUndefined("plugins", false);
SetDefaultBoolIfUndefined(options::kExperimentalFeatures, false);
SetDefaultBoolIfUndefined(options::kExperimentalCanvasFeatures, false);
bool node = SetDefaultBoolIfUndefined(options::kNodeIntegration, true);
SetDefaultBoolIfUndefined(options::kNodeIntegrationInWorker, false);
SetDefaultBoolIfUndefined(options::kWebviewTag, node);
SetDefaultBoolIfUndefined("sandbox", false);
SetDefaultBoolIfUndefined("nativeWindowOpen", false);
SetDefaultBoolIfUndefined(options::kContextIsolation, false);
SetDefaultBoolIfUndefined("javascript", true);
SetDefaultBoolIfUndefined("images", true);
SetDefaultBoolIfUndefined("textAreasAreResizable", true);
SetDefaultBoolIfUndefined("webgl", true);
SetDefaultBoolIfUndefined("webSecurity", true);
SetDefaultBoolIfUndefined("allowRunningInsecureContent", false);
#if defined(OS_MACOSX)
SetDefaultBoolIfUndefined(options::kScrollBounce, false);
#endif
SetDefaultBoolIfUndefined("offscreen", false);
last_web_preferences_.MergeDictionary(&web_preferences_);
}

WebContentsPreferences::~WebContentsPreferences() {
Expand All @@ -55,6 +77,16 @@ WebContentsPreferences::~WebContentsPreferences() {
instances_.end());
}

bool WebContentsPreferences::SetDefaultBoolIfUndefined(const std::string key,
bool val) {
bool existing;
if (!web_preferences_.GetBoolean(key, &existing)) {
web_preferences_.SetBoolean(key, val);
return val;
}
return existing;
}

void WebContentsPreferences::Merge(const base::DictionaryValue& extend) {
web_preferences_.MergeDictionary(&extend);
}
Expand All @@ -79,6 +111,12 @@ void WebContentsPreferences::AppendExtraCommandLineSwitches(

base::DictionaryValue& web_preferences = self->web_preferences_;

// We are appending args to a webContents so let's save the current state
// of our preferences object so that during the lifetime of the WebContents
// we can fetch the options used to initally configure the WebContents
self->last_web_preferences_.Clear();
self->last_web_preferences_.MergeDictionary(&web_preferences);

bool b;
// Check if plugins are enabled.
if (web_preferences.GetBoolean("plugins", &b) && b)
Expand Down
7 changes: 7 additions & 0 deletions atom/browser/web_contents_preferences.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ class WebContentsPreferences

// Returns the web preferences.
base::DictionaryValue* web_preferences() { return &web_preferences_; }
base::DictionaryValue* last_web_preferences() {
return &last_web_preferences_;
}

private:
friend class content::WebContentsUserData<WebContentsPreferences>;
Expand All @@ -65,6 +68,10 @@ class WebContentsPreferences

content::WebContents* web_contents_;
base::DictionaryValue web_preferences_;
base::DictionaryValue last_web_preferences_;

// Set preference value to given bool if user did not provide value
bool SetDefaultBoolIfUndefined(const std::string key, bool val);

// Get preferences value as integer possibly coercing it from a string
bool GetInteger(const std::string& attributeName, int* intValue);
Expand Down
4 changes: 2 additions & 2 deletions lib/browser/guest-view-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,15 +155,15 @@ const createGuest = function (embedder, params) {
// Forward internal web contents event to embedder to handle
// native window.open setup
guest.on('-add-new-contents', (...args) => {
if (guest.getWebPreferences().nativeWindowOpen === true) {
if (guest.getLastWebPreferences().nativeWindowOpen === true) {
const embedder = getEmbedder(guestInstanceId)
if (embedder != null) {
embedder.emit('-add-new-contents', ...args)
}
}
})
guest.on('-web-contents-created', (...args) => {
if (guest.getWebPreferences().nativeWindowOpen === true) {
if (guest.getLastWebPreferences().nativeWindowOpen === true) {
const embedder = getEmbedder(guestInstanceId)
if (embedder != null) {
embedder.emit('-web-contents-created', ...args)
Expand Down
8 changes: 4 additions & 4 deletions lib/browser/guest-window-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,12 @@ const mergeBrowserWindowOptions = function (embedder, options) {
mergeOptions(options, embedder.browserWindowOptions)
} else {
// Or only inherit webPreferences if it is a webview.
mergeOptions(options.webPreferences, embedder.getWebPreferences())
mergeOptions(options.webPreferences, embedder.getLastWebPreferences())
}

// Inherit certain option values from parent window
for (const [name, value] of inheritedWebPreferences) {
if (embedder.getWebPreferences()[name] === value) {
if (embedder.getLastWebPreferences()[name] === value) {
options.webPreferences[name] = value
}
}
Expand Down Expand Up @@ -168,8 +168,8 @@ const getGuestWindow = function (guestContents) {
// The W3C does not have anything on this, but from my understanding of the
// security model of |window.opener|, this should be fine.
const canAccessWindow = function (sender, target) {
return (target.getWebPreferences().openerId === sender.id) ||
(sender.getWebPreferences().nodeIntegration === true) ||
return (target.getLastWebPreferences().openerId === sender.id) ||
(sender.getLastWebPreferences().nodeIntegration === true) ||
isSameOrigin(sender.getURL(), target.getURL())
}

Expand Down
7 changes: 3 additions & 4 deletions spec/api-browser-window-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2691,10 +2691,9 @@ describe('BrowserWindow module', function () {
})
w.loadURL('file://' + fixtures + '/api/isolated.html')
})

it('enables context isolation on child windows', function (done) {
app.once('browser-window-created', function (event, window) {
assert.equal(window.webContents.getWebPreferences().contextIsolation, true)
it('enables context isolation on child windows', (done) => {
app.once('browser-window-created', (event, window) => {
assert.equal(window.webContents.getLastWebPreferences().contextIsolation, true)
done()
})
w.loadURL('file://' + fixtures + '/pages/window-open.html')
Expand Down
30 changes: 25 additions & 5 deletions spec/chromium-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -241,8 +241,28 @@ describe('chromium feature', function () {
b = window.open(windowUrl, '', 'nodeIntegration=no,show=no')
})

it('disables node integration when it is disabled on the parent window for chrome devtools URLs', function (done) {
var b
it('disables webviewTag when node integration is disabled on the parent window', (done) => {
let b
listener = (event) => {
assert.equal(event.data.isWebViewUndefined, true)
b.close()
done()
}
window.addEventListener('message', listener)

const windowUrl = require('url').format({
pathname: `${fixtures}/pages/window-opener-no-web-view-tag.html`,
protocol: 'file',
query: {
p: `${fixtures}/pages/window-opener-web-view.html`
},
slashes: true
})
b = window.open(windowUrl, '', 'nodeIntegration=no,show=no')
})

it('disables node integration when it is disabled on the parent window for chrome devtools URLs', (done) => {
let b
app.once('web-contents-created', (event, contents) => {
contents.once('did-finish-load', () => {
contents.executeJavaScript('typeof process').then((typeofProcessGlobal) => {
Expand All @@ -260,7 +280,7 @@ describe('chromium feature', function () {
app.once('web-contents-created', (event, contents) => {
contents.once('did-finish-load', () => {
app.once('browser-window-created', (event, window) => {
const preferences = window.webContents.getWebPreferences()
const preferences = window.webContents.getLastWebPreferences()
assert.equal(preferences.javascript, false)
window.destroy()
b.close()
Expand Down Expand Up @@ -486,7 +506,7 @@ describe('chromium feature', function () {
done()
}
window.addEventListener('message', listener)
w = window.open(url, '', 'show=no')
w = window.open(url, '', 'show=no,nodeIntegration=no')
})

it('works when origin matches', function (done) {
Expand All @@ -495,7 +515,7 @@ describe('chromium feature', function () {
done()
}
window.addEventListener('message', listener)
w = window.open(`file://${fixtures}/pages/window-opener-location.html`, '', 'show=no')
w = window.open(`file://${fixtures}/pages/window-opener-location.html`, '', 'show=no,nodeIntegration=no')
})

it('works when origin does not match opener but has node integration', function (done) {
Expand Down
15 changes: 15 additions & 0 deletions spec/fixtures/pages/window-opener-no-web-view-tag.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<html>
<body>
<script type="text/javascript" charset="utf-8">
var windowUrl = decodeURIComponent(window.location.search.substring(3))
var opened = window.open('file://' + windowUrl, '', 'webviewTag=yes,show=no')
window.addEventListener('message', function (event) {
try {
opened.close()
} finally {
window.opener.postMessage(event.data, '*')
}
})
</script>
</body>
</html>
9 changes: 9 additions & 0 deletions spec/fixtures/pages/window-opener-web-view.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<html>
<body>
<script type="text/javascript" charset="utf-8">
window. => {
window.opener.postMessage({isWebViewUndefined: typeof WebView === 'undefined'}, '*')
}
</script>
</body>
</html>
0