| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 | 
							- 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 };
 
 
  |