// Copyright (c) 2020 Shellyl_N and Authors // license: ISC // https://github.com/shellyln // tslint:disable: no-shadowed-variable // tslint:disable: function-constructor export const dummyTargetObject = {}; // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment export const { g: globalObj, o: objConstructor, f: funConstructor } = (() => { let globalObj = null; try { // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-implied-eval globalObj = Function('return this')(); } catch (e) { // Nothing to do. } if (! globalObj) { // Fall back (for CSP, etc...) if (typeof window === 'object' && window) { globalObj = window; } else if (typeof global === 'object' && global) { globalObj = global; } else if (typeof globalThis === 'object' && globalThis) { globalObj = globalThis; } else { globalObj = dummyTargetObject; } } // NOTE: ({}).constructor === Object // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment let objConstructor: ObjectConstructor = null as any; try { // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment objConstructor = (({}).constructor ?? Object) as any; } catch (e) { // Nothing to do. } if (! objConstructor) { // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment objConstructor = dummyTargetObject as any; } // NOTE: ({}).toString.constructor === Function // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment let funConstructor: FunctionConstructor = null as any; try { // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment funConstructor = (({}).toString.constructor ?? Function) as any; } catch (e) { // Nothing to do. } if (! funConstructor) { // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment funConstructor = dummyTargetObject as any; } return ({ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment g: globalObj, o: objConstructor, f: funConstructor }); })(); // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export function isUnsafeVarNames(target: any, varName: string) { if (target === globalObj || varName === '__proto__' || varName === '__defineGetter__' || varName === '__defineSetter__' || varName === '__lookupGetter__' || varName === '__lookupSetter__') { return true; } if (varName === 'prototype' || varName === 'constructor') { if (target === null || target === void 0 || typeof target === 'function') { return true; } } if (target === null || target === void 0 || target === objConstructor) { if (Object.prototype.hasOwnProperty.call(objConstructor, varName)) { return true; } } if (target === null || target === void 0 || target === funConstructor) { // checking 'call', 'arguments', 'caller', ... let con: any = funConstructor; while (con) { // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access if (Object.prototype.hasOwnProperty.call(con, varName)) { return true; } // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access con = con.__proto__; } } if (typeof target === 'function') { // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access if (! Object.prototype.hasOwnProperty.call(target, varName)) { // function's prototypes' members return true; } } return false; }