fix: prevent remote from messing with constructor names (#22820)
This commit is contained in:
parent
746266bd93
commit
b327478cf0
2 changed files with 17 additions and 4 deletions
|
@ -22,6 +22,8 @@ process.on('exit', () => {
|
||||||
ipcRendererInternal.send(command, contextId);
|
ipcRendererInternal.send(command, contextId);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const IS_REMOTE_PROXY = Symbol('is-remote-proxy');
|
||||||
|
|
||||||
// Convert the arguments object into an array of meta data.
|
// Convert the arguments object into an array of meta data.
|
||||||
function wrapArgs (args, visited = new Set()) {
|
function wrapArgs (args, visited = new Set()) {
|
||||||
const valueToMeta = (value) => {
|
const valueToMeta = (value) => {
|
||||||
|
@ -188,6 +190,7 @@ function proxyFunctionProperties (remoteMemberFunction, metaId, name) {
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
get: (target, property, receiver) => {
|
get: (target, property, receiver) => {
|
||||||
|
if (property === IS_REMOTE_PROXY) return true;
|
||||||
if (!Object.prototype.hasOwnProperty.call(target, property)) loadRemoteProperties();
|
if (!Object.prototype.hasOwnProperty.call(target, property)) loadRemoteProperties();
|
||||||
const value = target[property];
|
const value = target[property];
|
||||||
if (property === 'toString' && typeof value === 'function') {
|
if (property === 'toString' && typeof value === 'function') {
|
||||||
|
@ -247,7 +250,9 @@ function metaToValue (meta) {
|
||||||
|
|
||||||
setObjectMembers(ret, ret, meta.id, meta.members);
|
setObjectMembers(ret, ret, meta.id, meta.members);
|
||||||
setObjectPrototype(ret, ret, meta.id, meta.proto);
|
setObjectPrototype(ret, ret, meta.id, meta.proto);
|
||||||
Object.defineProperty(ret.constructor, 'name', { value: meta.name });
|
if (ret.constructor && ret.constructor[IS_REMOTE_PROXY]) {
|
||||||
|
Object.defineProperty(ret.constructor, 'name', { value: meta.name });
|
||||||
|
}
|
||||||
|
|
||||||
// Track delegate obj's lifetime & tell browser to clean up when object is GCed.
|
// Track delegate obj's lifetime & tell browser to clean up when object is GCed.
|
||||||
v8Util.setRemoteObjectFreer(ret, contextId, meta.id);
|
v8Util.setRemoteObjectFreer(ret, contextId, meta.id);
|
||||||
|
|
|
@ -283,11 +283,9 @@ ifdescribe(features.isRemoteModuleEnabled())('remote module', () => {
|
||||||
|
|
||||||
remotely.it(path.join(fixtures, 'module', 'no-prototype.js'))('should work when object has no prototype', (module: string) => {
|
remotely.it(path.join(fixtures, 'module', 'no-prototype.js'))('should work when object has no prototype', (module: string) => {
|
||||||
const a = require('electron').remote.require(module);
|
const a = require('electron').remote.require(module);
|
||||||
expect(a.foo.constructor.name).to.equal('');
|
|
||||||
expect(a.foo.bar).to.equal('baz');
|
expect(a.foo.bar).to.equal('baz');
|
||||||
expect(a.foo.baz).to.equal(false);
|
expect(a.foo.baz).to.equal(false);
|
||||||
expect(a.bar).to.equal(1234);
|
expect(a.bar).to.equal(1234);
|
||||||
expect(a.anonymous.constructor.name).to.equal('');
|
|
||||||
expect(a.getConstructorName(Object.create(null))).to.equal('');
|
expect(a.getConstructorName(Object.create(null))).to.equal('');
|
||||||
expect(a.getConstructorName(new (class {})())).to.equal('');
|
expect(a.getConstructorName(new (class {})())).to.equal('');
|
||||||
});
|
});
|
||||||
|
@ -436,7 +434,8 @@ ifdescribe(features.isRemoteModuleEnabled())('remote module', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('remote object in renderer', () => {
|
describe('remote object in renderer', () => {
|
||||||
const remotely = makeRemotely(makeWindow());
|
const win = makeWindow();
|
||||||
|
const remotely = makeRemotely(win);
|
||||||
|
|
||||||
remotely.it(fixtures)('can change its properties', (fixtures: string) => {
|
remotely.it(fixtures)('can change its properties', (fixtures: string) => {
|
||||||
const module = require('path').join(fixtures, 'module', 'property.js');
|
const module = require('path').join(fixtures, 'module', 'property.js');
|
||||||
|
@ -500,6 +499,15 @@ ifdescribe(features.isRemoteModuleEnabled())('remote module', () => {
|
||||||
global.gc();
|
global.gc();
|
||||||
stringify({});
|
stringify({});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('can handle objects without constructors', async () => {
|
||||||
|
win().webContents.once('remote-get-global', (event) => {
|
||||||
|
class Foo { bar () { return 'bar'; } }
|
||||||
|
Foo.prototype.constructor = undefined as any;
|
||||||
|
event.returnValue = new Foo();
|
||||||
|
});
|
||||||
|
expect(await remotely(() => require('electron').remote.getGlobal('test').bar())).to.equal('bar');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('remote value in browser', () => {
|
describe('remote value in browser', () => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue