UNPKG

mathjs

Version:

Math.js is an extensive math library for JavaScript and Node.js. It features a flexible expression parser with support for symbolic computation, comes with a large set of built-in functions and constants, and offers an integrated solution to work with dif

144 lines (134 loc) 4.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getSafeMethod = getSafeMethod; exports.getSafeProperty = getSafeProperty; exports.isPlainObject = isPlainObject; exports.isSafeArrayProperty = isSafeArrayProperty; exports.isSafeMethod = isSafeMethod; exports.isSafeObjectProperty = isSafeObjectProperty; exports.setSafeProperty = setSafeProperty; var _object = require("./object.js"); /** * Get a property of a plain object or array * Throws an error in case the object is not a plain object or the * property is not defined on the object itself * @param {Object} object * @param {string} prop * @return {*} Returns the property value when safe */ function getSafeProperty(object, prop) { if (isSafeObjectProperty(object, prop) || isSafeArrayProperty(object, prop)) { return object[prop]; } if (isSafeMethod(object, prop)) { throw new Error(`Cannot access method "${prop}" as a property`); } if (object === null || object === undefined) { throw new TypeError(`Cannot access property "${prop}": object is ${object}`); } throw new Error('No access to property "' + prop + '"'); } /** * Set a property on a plain object or array. * Throws an error in case the object is not a plain object or the * property would override an inherited property like .constructor or .toString * @param {Object} object * @param {string} prop * @param {*} value * @return {*} Returns the value */ function setSafeProperty(object, prop, value) { if (isSafeObjectProperty(object, prop) || isSafeArrayProperty(object, prop)) { object[prop] = value; return value; } throw new Error(`No access to property "${prop}"`); } /** * Test whether a property is safe for reading and writing on an object * For example .constructor and .__proto__ are not safe * @param {Object} object * @param {string} prop * @return {boolean} Returns true when safe */ function isSafeObjectProperty(object, prop) { if (!isPlainObject(object)) { return false; } return !(prop in Object.prototype); } /** * Test whether a property is safe for reading and writing on an Array * For example .__proto__ and .constructor are not safe * @param {unknown} array * @param {string | number} prop * @return {boolean} Returns true when safe */ function isSafeArrayProperty(array, prop) { if (!Array.isArray(array)) { return false; } return typeof prop === 'number' || typeof prop === 'string' && isInteger(prop) || prop === 'length'; } function isInteger(prop) { return /^\d+$/.test(prop); } /** * Validate whether a method is safe. * Throws an error when that's not the case. * @param {Object} object * @param {string} method * @return {function} Returns the method when valid */ function getSafeMethod(object, method) { if (!isSafeMethod(object, method)) { throw new Error('No access to method "' + method + '"'); } return object[method]; } /** * Check whether a method is safe. * Throws an error when that's not the case (for example for `constructor`). * @param {Object} object * @param {string} method * @return {boolean} Returns true when safe, false otherwise */ function isSafeMethod(object, method) { if (object === null || object === undefined || typeof object[method] !== 'function') { return false; } // UNSAFE: ghosted // e.g overridden toString // Note that IE10 doesn't support __proto__ and we can't do this check there. if ((0, _object.hasOwnProperty)(object, method) && Object.getPrototypeOf && method in Object.getPrototypeOf(object)) { return false; } // SAFE: whitelisted // e.g toString if (safeNativeMethods.has(method)) { return true; } // UNSAFE: inherited from Object prototype // e.g constructor if (method in Object.prototype) { // 'in' is used instead of hasOwnProperty for nodejs v0.10 // which is inconsistent on root prototypes. It is safe // here because Object.prototype is a root object return false; } // UNSAFE: inherited from Function prototype // e.g call, apply if (method in Function.prototype) { // 'in' is used instead of hasOwnProperty for nodejs v0.10 // which is inconsistent on root prototypes. It is safe // here because Function.prototype is a root object return false; } return true; } function isPlainObject(object) { return typeof object === 'object' && object && object.constructor === Object; } const safeNativeMethods = new Set(['toString', 'valueOf', 'toLocaleString']);