fix: disable contextBridge object identity caching (#21803)

* fix: disable contextBridge object identity caching

* cleanup

* chore: make non-const references raw pointers

* fix: zero-param constructors are not explicit

* refactor: use base::LinkedList

Co-authored-by: Jeremy Apthorp <nornagon@nornagon.net>
This commit is contained in:
Samuel Attard 2020-03-03 23:18:22 -08:00 committed by GitHub
parent a53a2aaa45
commit 2563681583
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 266 additions and 453 deletions

View file

@ -320,43 +320,6 @@ describe('contextBridge', () => {
expect(result).to.deep.equal([135, 135, 135])
})
it('it should follow expected simple rules of object identity', async () => {
await makeBindingWindow(() => {
const o: any = { value: 135 }
const sub = { thing: 7 }
o.a = sub
o.b = sub
contextBridge.exposeInMainWorld('example', {
o
})
})
const result = await callWithBindings((root: any) => {
return root.example.a === root.example.b
})
expect(result).to.equal(true)
})
it('it should follow expected complex rules of object identity', async () => {
await makeBindingWindow(() => {
let first: any = null
contextBridge.exposeInMainWorld('example', {
check: (arg: any) => {
if (first === null) {
first = arg
} else {
return first === arg
}
}
})
})
const result = await callWithBindings((root: any) => {
const o = { thing: 123 }
root.example.check(o)
return root.example.check(o)
})
expect(result).to.equal(true)
})
// Can only run tests which use the GCRunner in non-sandboxed environments
if (!useSandbox) {
it('should release the global hold on methods sent across contexts', async () => {
@ -377,133 +340,6 @@ describe('contextBridge', () => {
})
expect((await getGCInfo()).functionCount).to.equal(2)
})
it('should release the global hold on objects sent across contexts when the object proxy is de-reffed', async () => {
await makeBindingWindow(() => {
require('electron').ipcRenderer.on('get-gc-info', e => e.sender.send('gc-info', (contextBridge as any).debugGC()))
let myObj: any
contextBridge.exposeInMainWorld('example', {
setObj: (o: any) => {
myObj = o
},
getObj: () => myObj
})
})
await callWithBindings(async (root: any) => {
root.GCRunner.run()
})
// Initial Setup
let info = await getGCInfo()
expect(info.liveFromValues).to.equal(3)
expect(info.liveProxyValues).to.equal(3)
expect(info.objectCount).to.equal(6)
// Create Reference
await callWithBindings(async (root: any) => {
root.x = { value: 123 }
root.example.setObj(root.x)
root.GCRunner.run()
})
info = await getGCInfo()
expect(info.liveFromValues).to.equal(4)
expect(info.liveProxyValues).to.equal(4)
expect(info.objectCount).to.equal(8)
// Release Reference
await callWithBindings(async (root: any) => {
root.example.setObj(null)
root.GCRunner.run()
})
info = await getGCInfo()
expect(info.liveFromValues).to.equal(3)
expect(info.liveProxyValues).to.equal(3)
expect(info.objectCount).to.equal(6)
})
it('should release the global hold on objects sent across contexts when the object source is de-reffed', async () => {
await makeBindingWindow(() => {
require('electron').ipcRenderer.on('get-gc-info', e => e.sender.send('gc-info', (contextBridge as any).debugGC()))
let myObj: any
contextBridge.exposeInMainWorld('example', {
setObj: (o: any) => {
myObj = o
},
getObj: () => myObj
})
})
await callWithBindings(async (root: any) => {
root.GCRunner.run()
})
// Initial Setup
let info = await getGCInfo()
expect(info.liveFromValues).to.equal(3)
expect(info.liveProxyValues).to.equal(3)
expect(info.objectCount).to.equal(6)
// Create Reference
await callWithBindings(async (root: any) => {
root.x = { value: 123 }
root.example.setObj(root.x)
root.GCRunner.run()
})
info = await getGCInfo()
expect(info.liveFromValues).to.equal(4)
expect(info.liveProxyValues).to.equal(4)
expect(info.objectCount).to.equal(8)
// Release Reference
await callWithBindings(async (root: any) => {
delete root.x
root.GCRunner.run()
})
info = await getGCInfo()
expect(info.liveFromValues).to.equal(3)
expect(info.liveProxyValues).to.equal(3)
expect(info.objectCount).to.equal(6)
})
it('should not crash when the object source is de-reffed AND the object proxy is de-reffed', async () => {
await makeBindingWindow(() => {
require('electron').ipcRenderer.on('get-gc-info', e => e.sender.send('gc-info', (contextBridge as any).debugGC()))
let myObj: any
contextBridge.exposeInMainWorld('example', {
setObj: (o: any) => {
myObj = o
},
getObj: () => myObj
})
})
await callWithBindings(async (root: any) => {
root.GCRunner.run()
})
// Initial Setup
let info = await getGCInfo()
expect(info.liveFromValues).to.equal(3)
expect(info.liveProxyValues).to.equal(3)
expect(info.objectCount).to.equal(6)
// Create Reference
await callWithBindings(async (root: any) => {
root.x = { value: 123 }
root.example.setObj(root.x)
root.GCRunner.run()
})
info = await getGCInfo()
expect(info.liveFromValues).to.equal(4)
expect(info.liveProxyValues).to.equal(4)
expect(info.objectCount).to.equal(8)
// Release Reference
await callWithBindings(async (root: any) => {
delete root.x
root.example.setObj(null)
root.GCRunner.run()
})
info = await getGCInfo()
expect(info.liveFromValues).to.equal(3)
expect(info.liveProxyValues).to.equal(3)
expect(info.objectCount).to.equal(6)
})
}
it('it should not let you overwrite existing exposed things', async () => {