Track visited parents and null out cycles

This commit is contained in:
Kevin Sawicki 2017-01-04 14:50:05 -08:00
parent 12382f064b
commit 1944fdc962
3 changed files with 28 additions and 14 deletions

View file

@ -7,19 +7,25 @@ const hasProp = {}.hasOwnProperty
const frameToGuest = {} const frameToGuest = {}
// Copy attribute of |parent| to |child| if it is not defined in |child|. // Copy attribute of |parent| to |child| if it is not defined in |child|.
const mergeOptions = function (child, parent) { const mergeOptions = function (child, parent, visited) {
let key, value // Check for circular reference.
for (key in parent) { 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 if (!hasProp.call(parent, key)) continue
value = parent[key] if (key in child) continue
if (!(key in child)) {
if (typeof value === 'object') { const value = parent[key]
child[key] = mergeOptions({}, value) if (typeof value === 'object') {
} else { child[key] = mergeOptions({}, value, visited)
child[key] = value } else {
} child[key] = value
} }
} }
visited.delete(parent)
return child return child
} }

View file

@ -270,10 +270,13 @@ describe('chromium feature', function () {
w = BrowserWindow.fromId(ipcRenderer.sendSync('create-window-with-options-cycle')) w = BrowserWindow.fromId(ipcRenderer.sendSync('create-window-with-options-cycle'))
w.loadURL('file://' + fixtures + '/pages/window-open.html') w.loadURL('file://' + fixtures + '/pages/window-open.html')
w.webContents.once('new-window', (event, url, frameName, disposition, options) => { w.webContents.once('new-window', (event, url, frameName, disposition, options) => {
assert.deepEqual(options, { assert.equal(options.show, false)
show: false, assert.deepEqual(options.foo, {
foo: { bar: null,
bar: null baz: {
hello: {
world: true
}
} }
}) })
done() done()

View file

@ -237,6 +237,11 @@ ipcMain.on('create-window-with-options-cycle', (event) => {
// nulled out at the IPC layer // nulled out at the IPC layer
const foo = {} const foo = {}
foo.bar = foo foo.bar = foo
foo.baz = {
hello: {
world: true
}
}
const window = new BrowserWindow({show: false, foo: foo}) const window = new BrowserWindow({show: false, foo: foo})
event.returnValue = window.id event.returnValue = window.id
}) })