UNPKG

ses

Version:

Hardened JavaScript for Fearless Cooperation

70 lines (67 loc) 2.43 kB
import { objectHasOwnProperty } from './commons.js'; /** * @import {Reporter} from './reporting-types.js' */ /** * Delete `obj[prop]` or at least make it harmless. * * If the property was not expected, then emit a reporter-dependent warning * to bring attention to this case, so someone can determine what to do with it. * * If the property to be deleted is a function's `.prototype` property, this * will normally be because the function was supposed to be a * - builtin method or non-constructor function * - arrow function * - concise method * * all of whom are not supposed to have a `.prototype` property. Nevertheless, * on some platforms (like older versions of Hermes), or as a result of * some shim-based mods to the primordials (like core-js?), some of these * functions may accidentally be more like `function` functions with * an undeletable `.prototype` property. In these cases, if we can * set the value of that bogus `.prototype` property to `undefined`, * we do so, issuing a warning, rather than failing to initialize ses. * * @param {object} obj * @param {PropertyKey} prop * @param {boolean} known If deletion is expected, don't warn * @param {string} subPath Used for warning messages * @param {Reporter} reporter Where to issue warning or error. * @returns {void} */ export const cauterizeProperty = ( obj, prop, known, subPath, { warn, error }, ) => { // Either the object lacks a permit or the object doesn't match the // permit. // If the permit is specifically false, not merely undefined, // this is a property we expect to see because we know it exists in // some environments and we have expressly decided to exclude it. // Any other disallowed property is one we have not audited and we log // that we are removing it so we know to look into it, as happens when // the language evolves new features to existing intrinsics. if (!known) { warn(`Removing ${subPath}`); } try { delete obj[prop]; } catch (err) { if (objectHasOwnProperty(obj, prop)) { if (typeof obj === 'function' && prop === 'prototype') { obj.prototype = undefined; if (obj.prototype === undefined) { warn(`Tolerating undeletable ${subPath} === undefined`); return; } } error(`failed to delete ${subPath}`, err); } else { error(`deleting ${subPath} threw`, err); } throw err; } };