From e89b3ca1d1be42191e8b349c4800c4fcbbf09945 Mon Sep 17 00:00:00 2001 From: Alexey Kuzmin Date: Mon, 7 Dec 2020 20:20:50 +0300 Subject: [PATCH] fix: add a "set" trap to the "screen" module proxy (#26818) --- lib/browser/api/screen.ts | 44 +++++++++++++++++++----------------- spec-main/api-screen-spec.ts | 12 ++++++++++ 2 files changed, 35 insertions(+), 21 deletions(-) diff --git a/lib/browser/api/screen.ts b/lib/browser/api/screen.ts index d3e9aaee3d7b..5899e8b54720 100644 --- a/lib/browser/api/screen.ts +++ b/lib/browser/api/screen.ts @@ -2,37 +2,39 @@ const { createScreen } = process._linkedBinding('electron_common_screen'); let _screen: Electron.Screen; +const createScreenIfNeeded = () => { + if (_screen === undefined) { + _screen = createScreen(); + } +}; + // We can't call createScreen until after app.on('ready'), but this module // exposes an instance created by createScreen. In order to avoid // side-effecting and calling createScreen upon import of this module, instead // we export a proxy which lazily calls createScreen on first access. export default new Proxy({}, { - get: (target, prop: keyof Electron.Screen) => { - if (_screen === undefined) { - _screen = createScreen(); + get: (target, property: keyof Electron.Screen) => { + createScreenIfNeeded(); + const value = _screen[property]; + if (typeof value === 'function') { + return value.bind(_screen); } - const v = _screen[prop]; - if (typeof v === 'function') { - return v.bind(_screen); - } - return v; + return value; + }, + set: (target, property: string, value: unknown) => { + createScreenIfNeeded(); + return Reflect.set(_screen, property, value); }, ownKeys: () => { - if (_screen === undefined) { - _screen = createScreen(); - } + createScreenIfNeeded(); return Reflect.ownKeys(_screen); }, - has: (target, prop: string) => { - if (_screen === undefined) { - _screen = createScreen(); - } - return prop in _screen; + has: (target, property: string) => { + createScreenIfNeeded(); + return property in _screen; }, - getOwnPropertyDescriptor: (target, prop: string) => { - if (_screen === undefined) { - _screen = createScreen(); - } - return Reflect.getOwnPropertyDescriptor(_screen, prop); + getOwnPropertyDescriptor: (target, property: string) => { + createScreenIfNeeded(); + return Reflect.getOwnPropertyDescriptor(_screen, property); } }); diff --git a/spec-main/api-screen-spec.ts b/spec-main/api-screen-spec.ts index 7eb401940362..102e68155d28 100644 --- a/spec-main/api-screen-spec.ts +++ b/spec-main/api-screen-spec.ts @@ -2,6 +2,18 @@ import { expect } from 'chai'; import { screen } from 'electron/main'; describe('screen module', () => { + describe('methods reassignment', () => { + it('works for a selected method', () => { + const originalFunction = screen.getPrimaryDisplay; + try { + (screen as any).getPrimaryDisplay = () => null; + expect(screen.getPrimaryDisplay()).to.be.null(); + } finally { + screen.getPrimaryDisplay = originalFunction; + } + }); + }); + describe('screen.getCursorScreenPoint()', () => { it('returns a point object', () => { const point = screen.getCursorScreenPoint();