diff --git a/lib/renderer/api/remote.js b/lib/renderer/api/remote.js index dea3f404a06e..b3d3d2ab17cc 100644 --- a/lib/renderer/api/remote.js +++ b/lib/renderer/api/remote.js @@ -179,7 +179,15 @@ const proxyFunctionProperties = function (remoteMemberFunction, metaId, name) { }, get: (target, property, receiver) => { if (!target.hasOwnProperty(property)) loadRemoteProperties() - return target[property] + const value = target[property] + + // Bind toString to target if it is a function to avoid + // Function.prototype.toString is not generic errors + if (property === 'toString' && typeof value === 'function') { + return value.bind(target) + } + + return value }, ownKeys: (target) => { loadRemoteProperties() diff --git a/spec/api-ipc-spec.js b/spec/api-ipc-spec.js index e812eb5fef2a..47f2eef21685 100644 --- a/spec/api-ipc-spec.js +++ b/spec/api-ipc-spec.js @@ -161,6 +161,14 @@ describe('ipc module', function () { assert.equal(typeof remote.clipboard.readText, 'function') assert.equal(typeof remote.shell.openExternal, 'function') }) + + it('returns toString() of original function via toString()', function () { + const {readText} = remote.clipboard + assert(readText.toString().startsWith('function')) + + var {functionWithToStringProperty} = remote.require(path.join(fixtures, 'module', 'to-string-non-function.js')) + assert.equal(functionWithToStringProperty.toString, 'hello') + }) }) describe('remote object in renderer', function () { diff --git a/spec/fixtures/module/to-string-non-function.js b/spec/fixtures/module/to-string-non-function.js new file mode 100644 index 000000000000..3e91921037c5 --- /dev/null +++ b/spec/fixtures/module/to-string-non-function.js @@ -0,0 +1,4 @@ +function hello () { +} +hello.toString = 'hello' +module.exports = {functionWithToStringProperty: hello}