Skip to content

Commit

Permalink
fix: don't overwrite global constructor names in remote (#20637)
Browse files Browse the repository at this point in the history
* fix: don't overwrite global constructor names in remote

* fake constructor names better, and improve error serialization
  • Loading branch information
nornagon authored and zcbenz committed Oct 21, 2019
1 parent 820dab2 commit b155ebe
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 10 deletions.
16 changes: 14 additions & 2 deletions lib/browser/remote/server.ts
Expand Up @@ -245,6 +245,17 @@ type MetaTypeFromRenderer = {
length: number
}

const fakeConstructor = (constructor: Function, name: string) =>
new Proxy(Object, {
get (target, prop, receiver) {
if (prop === 'name') {
return name
} else {
return Reflect.get(target, prop, receiver)
}
}
})

// Convert array of meta data from renderer into array of real values.
const unwrapArgs = function (sender: electron.WebContents, frameId: number, contextId: string, args: any[]) {
const metaToValue = function (meta: MetaTypeFromRenderer): any {
Expand All @@ -262,8 +273,9 @@ const unwrapArgs = function (sender: electron.WebContents, frameId: number, cont
then: metaToValue(meta.then)
})
case 'object': {
const ret: any = {}
Object.defineProperty(ret.constructor, 'name', { value: meta.name })
const ret: any = meta.name !== 'Object' ? Object.create({
constructor: fakeConstructor(Object, meta.name)
}) : {}

for (const { name, value } of meta.members) {
ret[name] = metaToValue(value)
Expand Down
5 changes: 5 additions & 0 deletions lib/renderer/api/remote.js
Expand Up @@ -64,6 +64,11 @@ function wrapArgs (args, visited = new Set()) {
type: 'remote-object',
id: v8Util.getHiddenValue(value, 'atomId')
}
} else if (value instanceof Error) {
return {
type: 'value',
value
}
}

const meta = {
Expand Down
15 changes: 7 additions & 8 deletions spec/api-remote-spec.js
Expand Up @@ -498,17 +498,16 @@ ifdescribe(features.isRemoteModuleEnabled())('remote module', () => {
it('throws errors from the main process', () => {
expect(() => {
throwFunction()
}).to.throw()
}).to.throw(/undefined/)
})

it('throws custom errors from the main process', () => {
const err = new Error('error')
err.cause = new Error('cause')
err.prop = 'error prop'
it('tracks error cause', () => {
try {
throwFunction(err)
} catch (error) {
expect(error.cause).to.deep.equal(...resolveGetters(err))
throwFunction(new Error('error from main'))
expect.fail()
} catch (e) {
expect(e.message).to.match(/Could not call remote function/)
expect(e.cause.message).to.equal('error from main')
}
})
})
Expand Down

0 comments on commit b155ebe

Please sign in to comment.