Просмотр исходного кода

refactor: reuse setOwnProp for getter/setter

tophf 3 лет назад
Родитель
Сommit
65b3b45cbe

+ 1 - 3
src/injected/content/inject.js

@@ -45,9 +45,7 @@ if (IS_FIREFOX) {
     }
   }, true);
 } else {
-  safeDefineProperty(global, VAULT_WRITER, {
-    value: tellBridgeToWriteVault,
-  });
+  setOwnProp(global, VAULT_WRITER, tellBridgeToWriteVault, false);
 }
 
 addHandlers({

+ 12 - 6
src/injected/safe-globals-injected.js

@@ -38,16 +38,22 @@ export const getOwnProp = (obj, key, defVal) => {
   return defVal;
 };
 
-/** Workaround for array eavesdropping via prototype setters like '0','1',...
- * on `push` and `arr[i] = 123`, as well as via getters if you read beyond
- * its length or from an unassigned `hole`. */
-export const setOwnProp = (obj, key, value, mutable = true) => (
+/**
+ * @param {T} obj
+ * @param {string|Symbol} key
+ * @param {?} value
+ * @param {boolean} [mutable]
+ * @param {'set' | 'get'} [valueKey]
+ * @return {T}
+ * @template T
+ */
+export const setOwnProp = (obj, key, value, mutable = true, valueKey) => (
   defineProperty(obj, key, {
     __proto__: null,
-    value,
+    [valueKey || 'value']: value,
+    [!valueKey && 'writable']: mutable, // only allowed for 'value'
     configurable: mutable,
     enumerable: mutable,
-    writable: mutable,
   })
 );
 

+ 5 - 5
src/injected/web/gm-global-wrapper.js

@@ -1,6 +1,5 @@
 import { FastLookup, safeConcat } from './util';
 
-const CONFIGURABLE = 'configurable';
 const scopeSym = SafeSymbol.unscopables;
 const globalKeysSet = FastLookup();
 const globalKeys = (function makeGlobalKeys() {
@@ -73,21 +72,22 @@ export function makeGlobalWrapper(local) {
   /* Browsers may return [object Object] for Object.prototype.toString(window)
      on our `window` proxy so jQuery libs see it as a plain object and throw
      when trying to clone its recursive properties like `self` and `window`. */
-  safeDefineProperty(local, toStringTagSym, { get: () => 'Window' });
+  setOwnProp(local, toStringTagSym, () => 'Window', false, 'get');
   const events = createNullObj();
   const wrapper = new SafeProxy(local, {
     __proto__: null,
     defineProperty(_, name, desc) {
       if (name in local
       || !(_ = globalDesc[name] || updateGlobalDesc(name))
-      || _[CONFIGURABLE]) {
-        return safeDefineProperty(local, name, desc);
+      || _.configurable) {
+        /* It's up to caller to protect proto */// eslint-disable-next-line no-restricted-syntax
+        return defineProperty(local, name, desc);
       }
     },
     deleteProperty(_, name) {
       if ((_ = delete local[name])
       && (_ = globalDesc[name] || updateGlobalDesc(name))
-      && (_ = _[CONFIGURABLE])) {
+      && (_ = _.configurable)) {
         if (globals === globalKeysSet) {
           globals = globalKeysSet.clone();
         }