From 1944fdc962c58b3bb8d0cd0cceff8996b416c8a2 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 4 Jan 2017 14:50:05 -0800 Subject: [PATCH] Track visited parents and null out cycles --- lib/browser/guest-window-manager.js | 26 ++++++++++++++++---------- spec/chromium-spec.js | 11 +++++++---- spec/static/main.js | 5 +++++ 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/lib/browser/guest-window-manager.js b/lib/browser/guest-window-manager.js index 8212e50..c0a5efb 100644 --- a/lib/browser/guest-window-manager.js +++ b/lib/browser/guest-window-manager.js @@ -7,19 +7,25 @@ const hasProp = {}.hasOwnProperty const frameToGuest = {} // Copy attribute of |parent| to |child| if it is not defined in |child|. -const mergeOptions = function (child, parent) { - let key, value - for (key in parent) { +const mergeOptions = function (child, parent, visited) { + // Check for circular reference. + if (visited == null) visited = new Set() + if (visited.has(parent)) return + + visited.add(parent) + for (const key in parent) { if (!hasProp.call(parent, key)) continue - value = parent[key] - if (!(key in child)) { - if (typeof value === 'object') { - child[key] = mergeOptions({}, value) - } else { - child[key] = value - } + if (key in child) continue + + const value = parent[key] + if (typeof value === 'object') { + child[key] = mergeOptions({}, value, visited) + } else { + child[key] = value } } + visited.delete(parent) + return child } diff --git a/spec/chromium-spec.js b/spec/chromium-spec.js index 039fc1e..e663dcc 100644 --- a/spec/chromium-spec.js +++ b/spec/chromium-spec.js @@ -270,10 +270,13 @@ describe('chromium feature', function () { w = BrowserWindow.fromId(ipcRenderer.sendSync('create-window-with-options-cycle')) w.loadURL('file://' + fixtures + '/pages/window-open.html') w.webContents.once('new-window', (event, url, frameName, disposition, options) => { - assert.deepEqual(options, { - show: false, - foo: { - bar: null + assert.equal(options.show, false) + assert.deepEqual(options.foo, { + bar: null, + baz: { + hello: { + world: true + } } }) done() diff --git a/spec/static/main.js b/spec/static/main.js index aad8a64..9b9f6c0 100644 --- a/spec/static/main.js +++ b/spec/static/main.js @@ -237,6 +237,11 @@ ipcMain.on('create-window-with-options-cycle', (event) => { // nulled out at the IPC layer const foo = {} foo.bar = foo + foo.baz = { + hello: { + world: true + } + } const window = new BrowserWindow({show: false, foo: foo}) event.returnValue = window.id }) -- 2.7.4