Skip to content
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
12 changes: 7 additions & 5 deletions shell/browser/api/electron_api_web_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2166,6 +2166,7 @@ void WebContents::UpdateDraggableRegions(

void WebContents::DidStartNavigation(
content::NavigationHandle* navigation_handle) {
navigation_handle->SetSilentlyIgnoreErrors();
EmitNavigationEvent("did-start-navigation", navigation_handle);
}

Expand Down Expand Up @@ -2201,17 +2202,18 @@ void WebContents::DidFinishNavigation(
owner_window_->NotifyLayoutWindowControlsOverlay();
}

if (!navigation_handle->HasCommitted())
return;
bool is_main_frame = navigation_handle->IsInMainFrame();
content::RenderFrameHost* frame_host =
navigation_handle->GetRenderFrameHost();
content::RenderFrameHost* frame_host = nullptr;

if (navigation_handle->HasCommitted()) {
frame_host = navigation_handle->GetRenderFrameHost();
}
int frame_process_id = -1, frame_routing_id = -1;
if (frame_host) {
frame_process_id = frame_host->GetProcess()->GetID();
frame_routing_id = frame_host->GetRoutingID();
}
if (!navigation_handle->IsErrorPage()) {
if (!navigation_handle->IsErrorPage() && navigation_handle->HasCommitted()) {
// FIXME: All the Emit() calls below could potentially result in |this|
// being destroyed (by JS listening for the event and calling
// webContents.destroy()).
Expand Down
48 changes: 44 additions & 4 deletions spec/api-browser-window-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3716,11 +3716,21 @@ describe('BrowserWindow module', () => {
}
});

const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('<html><body>Blank Page</body></html>');
});
const serverUrl = (await listen(server)).url;

const preloadPath = path.join(mainFixtures, 'api', 'new-window-preload.js');
w.webContents.setWindowOpenHandler(() => ({ action: 'allow', overrideBrowserWindowOptions: { webPreferences: { preload: preloadPath } } }));
w.loadFile(path.join(fixtures, 'api', 'new-window.html'));
await w.loadFile(path.join(fixtures, 'api', 'new-window.html'), {
query: { url: serverUrl }
});
const [, { argv }] = await once(ipcMain, 'answer');
expect(argv).to.include('--enable-sandbox');

server.close();
});

it('should open windows with the options configured via setWindowOpenHandler handlers', async () => {
Expand All @@ -3731,15 +3741,25 @@ describe('BrowserWindow module', () => {
}
});

const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('<html><body>Blank Page</body></html>');
});
const serverUrl = (await listen(server)).url;

const preloadPath = path.join(mainFixtures, 'api', 'new-window-preload.js');
w.webContents.setWindowOpenHandler(() => ({ action: 'allow', overrideBrowserWindowOptions: { webPreferences: { preload: preloadPath, contextIsolation: false } } }));
w.loadFile(path.join(fixtures, 'api', 'new-window.html'));
await w.loadFile(path.join(fixtures, 'api', 'new-window.html'), {
query: { url: serverUrl }
});
const [[, childWebContents]] = await Promise.all([
once(app, 'web-contents-created') as Promise<[any, WebContents]>,
once(ipcMain, 'answer')
]);
const webPreferences = childWebContents.getLastWebPreferences();
expect(webPreferences!.contextIsolation).to.equal(false);

server.close();
});

it('should set ipc event sender correctly', async () => {
Expand Down Expand Up @@ -3909,10 +3929,20 @@ describe('BrowserWindow module', () => {
expect(content).to.equal('Hello');
});
it('blocks accessing cross-origin frames', async () => {
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('<html><body>Blank Page</body></html>');
});
const serverUrl = (await listen(server)).url;

const answer = once(ipcMain, 'answer');
w.loadFile(path.join(fixtures, 'api', 'native-window-open-cross-origin.html'));
await w.loadFile(path.join(fixtures, 'api', 'native-window-open-cross-origin.html'), {
query: { url: serverUrl }
});
const [, content] = await answer;
expect(content).to.equal('Failed to read a named property \'toString\' from \'Location\': Blocked a frame with origin "file://" from accessing a cross-origin frame.');

server.close();
});
it('opens window from <iframe> tags', async () => {
const answer = once(ipcMain, 'answer');
Expand Down Expand Up @@ -3973,6 +4003,12 @@ describe('BrowserWindow module', () => {
await webviewLoaded;
});
it('should open windows with the options configured via setWindowOpenHandler handlers', async () => {
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('<html><body>Blank Page</body></html>');
});
const serverUrl = (await listen(server)).url;

const preloadPath = path.join(mainFixtures, 'api', 'new-window-preload.js');
w.webContents.setWindowOpenHandler(() => ({
action: 'allow',
Expand All @@ -3983,13 +4019,17 @@ describe('BrowserWindow module', () => {
}
}
}));
w.loadFile(path.join(fixtures, 'api', 'new-window.html'));
await w.loadFile(path.join(fixtures, 'api', 'new-window.html'), {
query: { url: serverUrl }
});
const [[, childWebContents]] = await Promise.all([
once(app, 'web-contents-created') as Promise<[any, WebContents]>,
once(ipcMain, 'answer')
]);
const webPreferences = childWebContents.getLastWebPreferences();
expect(webPreferences!.contextIsolation).to.equal(false);

server.close();
});

describe('window.location', () => {
Expand Down
4 changes: 3 additions & 1 deletion spec/fixtures/api/native-window-open-cross-origin.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
<body>
<script type="text/javascript" charset="utf-8">
const {ipcRenderer} = require('electron')
const popup = window.open('http://127.0.0.1')
const urlParams = new URLSearchParams(window.location.search)
const targetUrl = urlParams.get('url') || 'http://127.0.0.1'
const popup = window.open(targetUrl)
const intervalID = setInterval(function () {
try {
if (popup.location.toString() !== 'about:blank') {
Expand Down
4 changes: 3 additions & 1 deletion spec/fixtures/api/new-window.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
<body>
<script type="text/javascript">
setTimeout(function () {
window.open('http://localhost')
const urlParams = new URLSearchParams(window.location.search)
const targetUrl = urlParams.get('url') || 'http://localhost'
window.open(targetUrl)
})
</script>
</body>
Expand Down
10 changes: 9 additions & 1 deletion spec/webview-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -659,19 +659,27 @@ describe('<webview> tag', function () {
});

it('blocks accessing cross-origin frames', async () => {
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('<html><body>Blank Page</body></html>');
});
const serverUrl = (await listen(server)).url;

// Don't wait for loading to finish.
loadWebView(w.webContents, {
allowpopups: 'on',
nodeintegration: 'on',
webpreferences: 'contextIsolation=no',
src: `file://${path.join(fixtures, 'api', 'native-window-open-cross-origin.html')}`
src: `file://${path.join(fixtures, 'api', 'native-window-open-cross-origin.html')}?url=${encodeURIComponent(serverUrl)}`
});

const [, content] = await once(ipcMain, 'answer');
const expectedContent =
/Failed to read a named property 'toString' from 'Location': Blocked a frame with origin "(.*?)" from accessing a cross-origin frame./;

expect(content).to.match(expectedContent);

server.close();
});

it('emits a browser-window-created event', async () => {
Expand Down