Comparing version 3.9.0 to 3.9.1
@@ -0,1 +1,6 @@ | ||
v3.9.1 (2020-03-29) | ||
------------------- | ||
[fix] Require helpers statically in main (XmiliaH) | ||
[fix] Fix for non-configurable property access (XmiliaH) | ||
v3.9.0 (2020-03-21) | ||
@@ -2,0 +7,0 @@ ------------------- |
@@ -21,2 +21,7 @@ /* global host */ | ||
local.Reflect.has = Reflect.has; | ||
local.Reflect.defineProperty = Reflect.defineProperty; | ||
local.Reflect.setPrototypeOf = Reflect.setPrototypeOf; | ||
local.Reflect.isExtensible = Reflect.isExtensible; | ||
local.Reflect.preventExtensions = Reflect.preventExtensions; | ||
local.Reflect.getOwnPropertyDescriptor = Reflect.getOwnPropertyDescriptor; | ||
@@ -55,3 +60,3 @@ // global is originally prototype of host.Object so it can be used to climb up from the sandbox. | ||
} catch (ex) { | ||
// Never pass the handled expcetion through! | ||
// Never pass the handled exception through! | ||
throw new VMError('Unable to perform instanceOf check.'); | ||
@@ -62,8 +67,6 @@ // This exception actually never get to the user. It only instructs the caller to return null because we wasn't able to perform instanceOf check. | ||
const SHARED_ARROW = ()=>{}; | ||
function SHARED_FUNC() {} | ||
const SHARED_ARRAY = []; | ||
const SHARED_OBJECT = {__proto__: null}; | ||
function getBaseObject(obj) { | ||
function createBaseObject(obj) { | ||
let base; | ||
if (typeof obj === 'function') { | ||
@@ -78,10 +81,18 @@ try { | ||
})(); | ||
// eslint-disable-next-line func-names | ||
base = function() {}; | ||
base.prototype = null; | ||
} catch (e) { | ||
return SHARED_ARROW; | ||
base = () => {}; | ||
} | ||
return SHARED_FUNC; | ||
} else if (host.Array.isArray(obj)) { | ||
return SHARED_ARRAY; | ||
base = []; | ||
} else { | ||
return {__proto__: null}; | ||
} | ||
return SHARED_OBJECT; | ||
if (!local.Reflect.setPrototypeOf(base, null)) { | ||
// Should not happen | ||
return null; | ||
} | ||
return base; | ||
} | ||
@@ -116,2 +127,40 @@ | ||
function unexpected() { | ||
throw new VMError('Should not happen'); | ||
} | ||
function doPreventExtensions(target, object, doProxy) { | ||
const keys = local.Reflect.ownKeys(object); | ||
for (let i = 0; i < keys.length; i++) { | ||
const key = keys[i]; | ||
let desc = local.Reflect.getOwnPropertyDescriptor(object, key); | ||
if (!desc) continue; | ||
if (!local.Reflect.setPrototypeOf(desc, null)) unexpected(); | ||
if (!desc.configurable) { | ||
const current = local.Reflect.getOwnPropertyDescriptor(target, key); | ||
if (current && !current.configurable) continue; | ||
if (desc.get || desc.set) { | ||
desc.get = doProxy(desc.get); | ||
desc.set = doProxy(desc.set); | ||
} else { | ||
desc.value = doProxy(desc.value); | ||
} | ||
} else { | ||
if (desc.get || desc.set) { | ||
desc = { | ||
__proto__: null, | ||
configurable: true, | ||
enumberable: desc.enumberable, | ||
writeable: true, | ||
value: null | ||
}; | ||
} else { | ||
desc.value = null; | ||
} | ||
} | ||
if (!local.Reflect.defineProperty(target, key, desc)) unexpected(); | ||
} | ||
if (!local.Reflect.preventExtensions(target)) unexpected(); | ||
} | ||
/** | ||
@@ -277,6 +326,8 @@ * Decontextify. | ||
let desc; | ||
if (!def) { | ||
return undefined; | ||
} else if (def.get || def.set) { | ||
return { | ||
desc = { | ||
__proto__: null, | ||
get: Decontextify.value(def.get) || undefined, | ||
@@ -288,3 +339,4 @@ set: Decontextify.value(def.set) || undefined, | ||
} else { | ||
return { | ||
desc = { | ||
__proto__: null, | ||
value: Decontextify.value(def.value), | ||
@@ -296,4 +348,22 @@ writable: def.writable === true, | ||
} | ||
if (!desc.configurable) { | ||
try { | ||
def = host.Object.getOwnPropertyDescriptor(target, prop); | ||
if (!def || def.configurable) { | ||
local.Reflect.defineProperty(target, prop, desc); | ||
} | ||
} catch (e) { | ||
// Should not happen. | ||
} | ||
} | ||
return desc; | ||
}; | ||
base.defineProperty = (target, key, descriptor) => { | ||
let success = false; | ||
try { | ||
success = local.Reflect.setPrototypeOf(descriptor, null); | ||
} catch (e) { | ||
// Should not happen | ||
} | ||
if (!success) return false; | ||
// There's a chance accessing a property throws an error so we must not access them | ||
@@ -316,6 +386,15 @@ // in try catch to prevent contextyfing local objects. | ||
try { | ||
return host.Object.defineProperty(target, key, propertyDescriptor); | ||
success = local.Reflect.defineProperty(object, key, propertyDescriptor); | ||
} catch (e) { | ||
throw Decontextify.value(e); | ||
} | ||
if (success && descriptor.configurable) { | ||
try { | ||
local.Reflect.defineProperty(target, key, descriptor); | ||
} catch (e) { | ||
// This should not happen. | ||
return false; | ||
} | ||
} | ||
return success; | ||
}; | ||
@@ -343,7 +422,18 @@ base.deleteProperty = (target, prop) => { | ||
base.isExtensible = target => { | ||
let result; | ||
try { | ||
return Decontextify.value(local.Object.isExtensible(object)); | ||
result = local.Reflect.isExtensible(object); | ||
} catch (e) { | ||
throw Decontextify.value(e); | ||
} | ||
if (!result) { | ||
try { | ||
if (local.Reflect.isExtensible(target)) { | ||
doPreventExtensions(target, object, obj => Contextify.value(obj, null, deepTraps, flags)); | ||
} | ||
} catch (e) { | ||
// Should not happen | ||
} | ||
} | ||
return result; | ||
}; | ||
@@ -358,8 +448,18 @@ base.ownKeys = target => { | ||
base.preventExtensions = target => { | ||
let success; | ||
try { | ||
local.Object.preventExtensions(object); | ||
return true; | ||
success = local.Reflect.preventExtensions(object); | ||
} catch (e) { | ||
throw Decontextify.value(e); | ||
} | ||
if (success) { | ||
try { | ||
if (local.Reflect.isExtensible(target)) { | ||
doPreventExtensions(target, object, obj => Contextify.value(obj, null, deepTraps, flags)); | ||
} | ||
} catch (e) { | ||
// Should not happen | ||
} | ||
} | ||
return success; | ||
}; | ||
@@ -382,2 +482,3 @@ base.enumerate = target => { | ||
ownKeys: base.ownKeys, | ||
// TODO this get will call getOwnPropertyDescriptor of target all the time. | ||
get: origGet | ||
@@ -403,5 +504,5 @@ }; | ||
const proxy = new host.Proxy(getBaseObject(object), base); | ||
const proxy = new host.Proxy(createBaseObject(object), base); | ||
Decontextified.set(proxy, object); | ||
// We need two proxys since nodes inspect just removes one. | ||
// We need two proxies since nodes inspect just removes one. | ||
const proxy2 = new host.Proxy(proxy, shallow); | ||
@@ -635,6 +736,8 @@ Decontextify.proxies.set(object, proxy2); | ||
let desc; | ||
if (!def) { | ||
return undefined; | ||
} else if (def.get || def.set) { | ||
return { | ||
desc = { | ||
__proto__: null, | ||
get: Contextify.value(def.get, null, deepTraps, flags) || undefined, | ||
@@ -646,3 +749,4 @@ set: Contextify.value(def.set, null, deepTraps, flags) || undefined, | ||
} else { | ||
return { | ||
desc = { | ||
__proto__: null, | ||
value: Contextify.value(def.value, null, deepTraps, flags), | ||
@@ -654,4 +758,22 @@ writable: def.writable === true, | ||
} | ||
if (!desc.configurable) { | ||
try { | ||
def = host.Object.getOwnPropertyDescriptor(target, prop); | ||
if (!def || def.configurable) { | ||
local.Reflect.defineProperty(target, prop, desc); | ||
} | ||
} catch (e) { | ||
// Should not happen. | ||
} | ||
} | ||
return desc; | ||
}; | ||
base.defineProperty = (target, key, descriptor) => { | ||
let success = false; | ||
try { | ||
success = local.Reflect.setPrototypeOf(descriptor, null); | ||
} catch (e) { | ||
// Should not happen | ||
} | ||
if (!success) return false; | ||
// There's a chance accessing a property throws an error so we must not access them | ||
@@ -682,6 +804,15 @@ // in try catch to prevent contextyfing local objects. | ||
try { | ||
return host.Object.defineProperty(object, key, propertyDescriptor); | ||
success = host.Reflect.defineProperty(object, key, propertyDescriptor); | ||
} catch (e) { | ||
throw Contextify.value(e); | ||
} | ||
if (success && descriptor.configurable) { | ||
try { | ||
local.Reflect.defineProperty(target, key, descriptor); | ||
} catch (e) { | ||
// This should not happen. | ||
return false; | ||
} | ||
} | ||
return success; | ||
}; | ||
@@ -709,7 +840,18 @@ base.deleteProperty = (target, prop) => { | ||
base.isExtensible = target => { | ||
let result; | ||
try { | ||
return Contextify.value(host.Object.isExtensible(object)); | ||
result = host.Reflect.isExtensible(object); | ||
} catch (e) { | ||
throw Contextify.value(e); | ||
} | ||
if (!result) { | ||
try { | ||
if (local.Reflect.isExtensible(target)) { | ||
doPreventExtensions(target, object, obj => Decontextify.value(obj, null, deepTraps, flags)); | ||
} | ||
} catch (e) { | ||
// Should not happen | ||
} | ||
} | ||
return result; | ||
}; | ||
@@ -724,8 +866,18 @@ base.ownKeys = target => { | ||
base.preventExtensions = target => { | ||
let success; | ||
try { | ||
host.Object.preventExtensions(object); | ||
return true; | ||
success = local.Reflect.preventExtensions(object); | ||
} catch (e) { | ||
throw Contextify.value(e); | ||
} | ||
if (success) { | ||
try { | ||
if (local.Reflect.isExtensible(target)) { | ||
doPreventExtensions(target, object, obj => Decontextify.value(obj, null, deepTraps, flags)); | ||
} | ||
} catch (e) { | ||
// Should not happen | ||
} | ||
} | ||
return success; | ||
}; | ||
@@ -740,3 +892,3 @@ base.enumerate = target => { | ||
const proxy = new host.Proxy(getBaseObject(object), host.Object.assign(base, traps, deepTraps)); | ||
const proxy = new host.Proxy(createBaseObject(object), host.Object.assign(base, traps, deepTraps)); | ||
Contextify.proxies.set(object, proxy); | ||
@@ -743,0 +895,0 @@ Contextified.set(proxy, object); |
@@ -28,2 +28,3 @@ /* eslint-disable global-require, no-use-before-define */ | ||
const {INSPECT_MAX_BYTES} = require('buffer'); | ||
const helpers = require('./helpers.js'); | ||
@@ -1185,3 +1186,4 @@ /** | ||
VM, | ||
NodeVM | ||
NodeVM, | ||
helpers | ||
}; | ||
@@ -1188,0 +1190,0 @@ |
@@ -9,3 +9,2 @@ /* eslint-disable no-shadow, no-invalid-this */ | ||
const pa = host.require('path'); | ||
const {match} = host.require('../lib/wildcard'); | ||
@@ -269,3 +268,3 @@ const BUILTIN_MODULES = host.process.binding('natives'); | ||
const isWhitelisted = external.some(ext => match(ext, moduleName)) || (transitive && parentAllowsTransitive); | ||
const isWhitelisted = external.some(ext => host.helpers.match(ext, moduleName)) || (transitive && parentAllowsTransitive); | ||
if (!isWhitelisted) { | ||
@@ -272,0 +271,0 @@ throw new VMError(`The module '${moduleName}' is not whitelisted in VM.`, 'EDENIED'); |
@@ -16,3 +16,3 @@ { | ||
], | ||
"version": "3.9.0", | ||
"version": "3.9.1", | ||
"main": "index.js", | ||
@@ -19,0 +19,0 @@ "repository": "github:patriksimek/vm2", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
113112
2738