simple-squiggle/node_modules/mathjs/lib/esm/utils/customs.js

173 lines
4.7 KiB
JavaScript

import { hasOwnProperty } from './object.js';
/**
* 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 + '"');
}
function getSafeProperties(object) {
return Object.keys(object).filter(prop => hasOwnProperty(object, prop));
}
function hasSafeProperty(object, prop) {
return prop in object;
}
/**
* 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 (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 (hasOwnProperty(object, method) && Object.getPrototypeOf && method in Object.getPrototypeOf(object)) {
return false;
} // SAFE: whitelisted
// e.g toString
if (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
};
export { getSafeProperty };
export { setSafeProperty };
export { isSafeProperty };
export { hasSafeProperty };
export { getSafeProperties };
export { validateSafeMethod };
export { isSafeMethod };
export { isPlainObject };