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

171 lines (138 loc) 5.11 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getSafeProperty = getSafeProperty; exports.setSafeProperty = setSafeProperty; exports.isSafeProperty = isSafeProperty; exports.validateSafeMethod = validateSafeMethod; exports.isSafeMethod = isSafeMethod; exports.isPlainObject = isPlainObject; var _object = require("./object.js"); function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } /** * Get a property of a plain object * 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) { // only allow getting safe properties of a plain object if (isPlainObject(object) && isSafeProperty(object, prop)) { return object[prop]; } if (typeof object[prop] === 'function' && isSafeMethod(object, prop)) { throw new Error('Cannot access method "' + prop + '" as a property'); } throw new Error('No access to property "' + prop + '"'); } /** * Set a property on a plain object. * 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 */ // TODO: merge this function into access.js? function setSafeProperty(object, prop, value) { // only allow setting safe properties of a plain object if (isPlainObject(object) && isSafeProperty(object, prop)) { object[prop] = value; return value; } throw new Error('No access to property "' + prop + '"'); } /** * Test whether a property is safe to use for an object. * For example .toString and .constructor are not safe * @param {string} prop * @return {boolean} Returns true when safe */ function isSafeProperty(object, prop) { if (!object || _typeof(object) !== 'object') { return false; } // SAFE: whitelisted // e.g length if ((0, _object.hasOwnProperty)(safeNativeProperties, prop)) { return true; } // UNSAFE: inherited from Object prototype // e.g constructor if (prop 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 (prop 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; } /** * Validate whether a method is safe. * Throws an error when that's not the case. * @param {Object} object * @param {string} method */ // TODO: merge this function into assign.js? function validateSafeMethod(object, method) { if (!isSafeMethod(object, method)) { throw new Error('No access to method "' + 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 ((0, _object.hasOwnProperty)(safeNativeMethods, 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; } var safeNativeProperties = { length: true, name: true }; var safeNativeMethods = { toString: true, valueOf: true, toLocaleString: true };