diff --git a/lib/browser/rpc-server.js b/lib/browser/rpc-server.js index 13d6f882c2e1..8d543f2d7d30 100644 --- a/lib/browser/rpc-server.js +++ b/lib/browser/rpc-server.js @@ -360,15 +360,16 @@ ipcMain.on('ELECTRON_BROWSER_MEMBER_CALL', function (event, id, method, args) { } }) -ipcMain.on('ELECTRON_BROWSER_MEMBER_SET', function (event, id, name, value) { +ipcMain.on('ELECTRON_BROWSER_MEMBER_SET', function (event, id, name, args) { try { + args = unwrapArgs(event.sender, args) let obj = objectsRegistry.get(id) if (obj == null) { throwRPCError(`Cannot set property '${name}' on missing remote object ${id}`) } - obj[name] = value + obj[name] = args[0] event.returnValue = null } catch (error) { event.returnValue = exceptionToMeta(error) diff --git a/lib/renderer/api/remote.js b/lib/renderer/api/remote.js index f65d61790ace..5e790133d383 100644 --- a/lib/renderer/api/remote.js +++ b/lib/renderer/api/remote.js @@ -139,7 +139,8 @@ const setObjectMembers = function (ref, object, metaId, members) { // Only set setter when it is writable. if (member.writable) { descriptor.set = function (value) { - const meta = ipcRenderer.sendSync('ELECTRON_BROWSER_MEMBER_SET', metaId, member.name, value) + const args = wrapArgs([value]) + const meta = ipcRenderer.sendSync('ELECTRON_BROWSER_MEMBER_SET', metaId, member.name, args) // Meta will be non-null when a setter error occurred so parse it // to a value so it gets re-thrown. if (meta != null) { diff --git a/spec/api-ipc-spec.js b/spec/api-ipc-spec.js index c5e38e83e4db..fb4278d180fb 100644 --- a/spec/api-ipc-spec.js +++ b/spec/api-ipc-spec.js @@ -175,8 +175,14 @@ describe('ipc module', function () { it('can change its properties', function () { var property = remote.require(path.join(fixtures, 'module', 'property.js')) assert.equal(property.property, 1127) + + property.property = null + assert.equal(property.property, null) + property.property = undefined + assert.equal(property.property, undefined) property.property = 1007 assert.equal(property.property, 1007) + assert.equal(property.getFunctionProperty(), 'foo-browser') property.func.property = 'bar' assert.equal(property.getFunctionProperty(), 'bar-browser') @@ -199,6 +205,14 @@ describe('ipc module', function () { }, /setting error/) }) + it('can set a remote property with a remote object', function () { + const foo = remote.require(path.join(fixtures, 'module', 'remote-object-set.js')) + + assert.doesNotThrow(function () { + foo.bar = remote.getCurrentWindow() + }) + }) + it('can construct an object from its member', function () { var call = remote.require(path.join(fixtures, 'module', 'call.js')) var obj = new call.constructor() diff --git a/spec/fixtures/module/remote-object-set.js b/spec/fixtures/module/remote-object-set.js new file mode 100644 index 000000000000..5fefbf5cf36a --- /dev/null +++ b/spec/fixtures/module/remote-object-set.js @@ -0,0 +1,11 @@ +const {BrowserWindow} = require('electron') + +class Foo { + set bar (value) { + if (!(value instanceof BrowserWindow)) { + throw new Error('setting error') + } + } +} + +module.exports = new Foo()