1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-24 15:19:26 -05:00

feat: vm rewrite (#24596)

rewrite vm implementation to increase compat.
vm.Module+importModuleDynamically callbacks should be added in a
followup.
This commit is contained in:
snek 2024-08-06 14:52:53 +02:00 committed by GitHub
parent c0e9512b39
commit 897159dc6e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
54 changed files with 3609 additions and 266 deletions

View file

@ -303,8 +303,10 @@ deno_core::extension!(deno_node,
ops::vm::op_vm_create_script,
ops::vm::op_vm_create_context,
ops::vm::op_vm_script_run_in_context,
ops::vm::op_vm_script_run_in_this_context,
ops::vm::op_vm_is_context,
ops::vm::op_vm_compile_function,
ops::vm::op_vm_script_get_source_map_url,
ops::vm::op_vm_script_create_cached_data,
ops::idna::op_node_idna_domain_to_ascii,
ops::idna::op_node_idna_domain_to_unicode,
ops::idna::op_node_idna_punycode_to_ascii,
@ -620,7 +622,7 @@ deno_core::extension!(deno_node,
"node:util" = "util.ts",
"node:util/types" = "util/types.ts",
"node:v8" = "v8.ts",
"node:vm" = "vm.ts",
"node:vm" = "vm.js",
"node:worker_threads" = "worker_threads.ts",
"node:zlib" = "zlib.ts",
],
@ -643,6 +645,11 @@ deno_core::extension!(deno_node,
customizer = |ext: &mut deno_core::Extension| {
let mut external_references = Vec::with_capacity(14);
vm::QUERY_MAP_FN.with(|query| {
external_references.push(ExternalReference {
named_query: *query,
});
});
vm::GETTER_MAP_FN.with(|getter| {
external_references.push(ExternalReference {
named_getter: *getter,
@ -653,6 +660,11 @@ deno_core::extension!(deno_node,
named_setter: *setter,
});
});
vm::DESCRIPTOR_MAP_FN.with(|descriptor| {
external_references.push(ExternalReference {
named_getter: *descriptor,
});
});
vm::DELETER_MAP_FN.with(|deleter| {
external_references.push(ExternalReference {
named_deleter: *deleter,
@ -668,12 +680,12 @@ deno_core::extension!(deno_node,
named_definer: *definer,
});
});
vm::DESCRIPTOR_MAP_FN.with(|descriptor| {
external_references.push(ExternalReference {
named_getter: *descriptor,
});
});
vm::INDEXED_QUERY_MAP_FN.with(|query| {
external_references.push(ExternalReference {
indexed_query: *query,
});
});
vm::INDEXED_GETTER_MAP_FN.with(|getter| {
external_references.push(ExternalReference {
indexed_getter: *getter,
@ -684,6 +696,11 @@ deno_core::extension!(deno_node,
indexed_setter: *setter,
});
});
vm::INDEXED_DESCRIPTOR_MAP_FN.with(|descriptor| {
external_references.push(ExternalReference {
indexed_getter: *descriptor,
});
});
vm::INDEXED_DELETER_MAP_FN.with(|deleter| {
external_references.push(ExternalReference {
indexed_deleter: *deleter,
@ -694,9 +711,9 @@ deno_core::extension!(deno_node,
indexed_definer: *definer,
});
});
vm::INDEXED_DESCRIPTOR_MAP_FN.with(|descriptor| {
vm::INDEXED_ENUMERATOR_MAP_FN.with(|enumerator| {
external_references.push(ExternalReference {
indexed_getter: *descriptor,
enumerator: *enumerator,
});
});

View file

@ -14,7 +14,6 @@ pub mod require;
pub mod util;
pub mod v8;
pub mod vm;
mod vm_internal;
pub mod winerror;
pub mod worker_threads;
pub mod zlib;

File diff suppressed because it is too large Load diff

View file

@ -746,6 +746,9 @@ function validateThrownError(
message = error;
error = undefined;
}
if (error?.prototype !== undefined && e instanceof error) {
return true;
}
if (
typeof error === "function" &&
(error === Error || ObjectPrototypeIsPrototypeOf(Error, error))

359
ext/node/polyfills/vm.js Normal file
View file

@ -0,0 +1,359 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
// Copyright Joyent, Inc. and Node.js contributors. All rights reserved. MIT license.
import { Buffer } from "node:buffer";
import { notImplemented } from "ext:deno_node/_utils.ts";
import {
op_vm_compile_function,
op_vm_create_context,
op_vm_create_script,
op_vm_is_context,
op_vm_script_create_cached_data,
op_vm_script_get_source_map_url,
op_vm_script_run_in_context,
} from "ext:core/ops";
import {
validateArray,
validateBoolean,
validateBuffer,
validateInt32,
validateObject,
validateOneOf,
validateString,
validateStringArray,
validateUint32,
} from "ext:deno_node/internal/validators.mjs";
import { ERR_INVALID_ARG_TYPE } from "ext:deno_node/internal/errors.ts";
import { primordials } from "ext:core/mod.js";
const { Symbol, ArrayPrototypeForEach } = primordials;
const kParsingContext = Symbol("script parsing context");
export class Script {
#inner;
constructor(code, options = {}) {
code = `${code}`;
if (typeof options === "string") {
options = { filename: options };
} else {
validateObject(options, "options");
}
const {
filename = "evalmachine.<anonymous>",
lineOffset = 0,
columnOffset = 0,
cachedData,
produceCachedData = false,
// importModuleDynamically,
[kParsingContext]: parsingContext,
} = options;
validateString(filename, "options.filename");
validateInt32(lineOffset, "options.lineOffset");
validateInt32(columnOffset, "options.columnOffset");
if (cachedData !== undefined) {
validateBuffer(cachedData, "options.cachedData");
}
validateBoolean(produceCachedData, "options.produceCachedData");
// const hostDefinedOptionId =
// getHostDefinedOptionId(importModuleDynamically, filename);
const result = op_vm_create_script(
code,
filename,
lineOffset,
columnOffset,
cachedData,
produceCachedData,
parsingContext,
);
this.#inner = result.value;
this.cachedDataProduced = result.cached_data_produced;
this.cachedDataRejected = result.cached_data_rejected;
this.cachedData = result.cached_data
? Buffer.from(result.cached_data)
: undefined;
}
#runInContext(contextifiedObject, options = {}) {
validateObject(options, "options");
let timeout = options.timeout;
if (timeout === undefined) {
timeout = -1;
} else {
validateUint32(timeout, "options.timeout", true);
}
const {
displayErrors = true,
breakOnSigint = false,
} = options;
validateBoolean(displayErrors, "options.displayErrors");
validateBoolean(breakOnSigint, "options.breakOnSigint");
//if (breakOnSigint && process.listenerCount('SIGINT') > 0) {
// return sigintHandlersWrap(super.runInContext, this, args);
//}
return op_vm_script_run_in_context(
this.#inner,
contextifiedObject,
timeout,
displayErrors,
breakOnSigint,
);
}
runInThisContext(options) {
return this.#runInContext(null, options);
}
runInContext(contextifiedObject, options) {
validateContext(contextifiedObject);
return this.#runInContext(contextifiedObject, options);
}
runInNewContext(contextObject, options) {
const context = createContext(contextObject, getContextOptions(options));
return this.runInContext(context, options);
}
get sourceMapURL() {
return op_vm_script_get_source_map_url(this.#inner);
}
createCachedData() {
return Buffer.from(op_vm_script_create_cached_data(this.#inner));
}
}
function validateContext(contextifiedObject) {
if (!isContext(contextifiedObject)) {
throw new ERR_INVALID_ARG_TYPE(
"contextifiedObject",
"vm.Context",
contextifiedObject,
);
}
}
function getContextOptions(options) {
if (!options) {
return {};
}
const contextOptions = {
name: options.contextName,
origin: options.contextOrigin,
codeGeneration: undefined,
microtaskMode: options.microtaskMode,
};
if (contextOptions.name !== undefined) {
validateString(contextOptions.name, "options.contextName");
}
if (contextOptions.origin !== undefined) {
validateString(contextOptions.origin, "options.contextOrigin");
}
if (options.contextCodeGeneration !== undefined) {
validateObject(
options.contextCodeGeneration,
"options.contextCodeGeneration",
);
const { strings, wasm } = options.contextCodeGeneration;
if (strings !== undefined) {
validateBoolean(strings, "options.contextCodeGeneration.strings");
}
if (wasm !== undefined) {
validateBoolean(wasm, "options.contextCodeGeneration.wasm");
}
contextOptions.codeGeneration = { strings, wasm };
}
if (options.microtaskMode !== undefined) {
validateString(options.microtaskMode, "options.microtaskMode");
}
return contextOptions;
}
let defaultContextNameIndex = 1;
export function createContext(contextObject = {}, options = {}) {
if (isContext(contextObject)) {
return contextObject;
}
validateObject(options, "options");
const {
name = `VM Context ${defaultContextNameIndex++}`,
origin,
codeGeneration,
microtaskMode,
// importModuleDynamically,
} = options;
validateString(name, "options.name");
if (origin !== undefined) {
validateString(origin, "options.origin");
}
if (codeGeneration !== undefined) {
validateObject(codeGeneration, "options.codeGeneration");
}
let strings = true;
let wasm = true;
if (codeGeneration !== undefined) {
({ strings = true, wasm = true } = codeGeneration);
validateBoolean(strings, "options.codeGeneration.strings");
validateBoolean(wasm, "options.codeGeneration.wasm");
}
validateOneOf(microtaskMode, "options.microtaskMode", [
"afterEvaluate",
undefined,
]);
const microtaskQueue = microtaskMode === "afterEvaluate";
// const hostDefinedOptionId =
// getHostDefinedOptionId(importModuleDynamically, name);
op_vm_create_context(
contextObject,
name,
origin,
strings,
wasm,
microtaskQueue,
);
// Register the context scope callback after the context was initialized.
// registerImportModuleDynamically(contextObject, importModuleDynamically);
return contextObject;
}
export function createScript(code, options) {
return new Script(code, options);
}
export function runInContext(code, contextifiedObject, options) {
validateContext(contextifiedObject);
if (typeof options === "string") {
options = {
filename: options,
[kParsingContext]: contextifiedObject,
};
} else {
options = {
...options,
[kParsingContext]: contextifiedObject,
};
}
return createScript(code, options)
.runInContext(contextifiedObject, options);
}
export function runInNewContext(code, contextObject, options) {
if (typeof options === "string") {
options = { filename: options };
}
contextObject = createContext(contextObject, getContextOptions(options));
options = { ...options, [kParsingContext]: contextObject };
return createScript(code, options).runInNewContext(contextObject, options);
}
export function runInThisContext(code, options) {
if (typeof options === "string") {
options = { filename: options };
}
return createScript(code, options).runInThisContext(options);
}
export function isContext(object) {
validateObject(object, "object", { allowArray: true });
return op_vm_is_context(object);
}
export function compileFunction(code, params, options = {}) {
validateString(code, "code");
if (params !== undefined) {
validateStringArray(params, "params");
}
const {
filename = "",
columnOffset = 0,
lineOffset = 0,
cachedData = undefined,
produceCachedData = false,
parsingContext = undefined,
contextExtensions = [],
// importModuleDynamically,
} = options;
validateString(filename, "options.filename");
validateInt32(columnOffset, "options.columnOffset");
validateInt32(lineOffset, "options.lineOffset");
if (cachedData !== undefined) {
validateBuffer(cachedData, "options.cachedData");
}
validateBoolean(produceCachedData, "options.produceCachedData");
if (parsingContext !== undefined) {
if (
typeof parsingContext !== "object" ||
parsingContext === null ||
!isContext(parsingContext)
) {
throw new ERR_INVALID_ARG_TYPE(
"options.parsingContext",
"Context",
parsingContext,
);
}
}
validateArray(contextExtensions, "options.contextExtensions");
ArrayPrototypeForEach(contextExtensions, (extension, i) => {
const name = `options.contextExtensions[${i}]`;
validateObject(extension, name, { nullable: true });
});
// const hostDefinedOptionId =
// getHostDefinedOptionId(importModuleDynamically, filename);
const result = op_vm_compile_function(
code,
filename,
lineOffset,
columnOffset,
cachedData,
produceCachedData,
parsingContext,
contextExtensions,
params,
);
result.value.cachedDataProduced = result.cached_data_produced;
result.value.cachedDataRejected = result.cached_data_rejected;
result.value.cachedData = result.cached_data
? Buffer.from(result.cached_data)
: undefined;
return result.value;
}
export function measureMemory(_options) {
notImplemented("measureMemory");
}
export default {
Script,
createContext,
createScript,
runInContext,
runInNewContext,
runInThisContext,
isContext,
compileFunction,
measureMemory,
};

View file

@ -1,100 +0,0 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
// deno-lint-ignore-file no-explicit-any
import { notImplemented } from "ext:deno_node/_utils.ts";
import {
op_vm_create_context,
op_vm_create_script,
op_vm_is_context,
op_vm_script_run_in_context,
op_vm_script_run_in_this_context,
} from "ext:core/ops";
export class Script {
#inner;
constructor(code: string, _options = {}) {
this.#inner = op_vm_create_script(code);
}
runInThisContext(_options: any) {
return op_vm_script_run_in_this_context(this.#inner);
}
runInContext(contextifiedObject: any, _options: any) {
return op_vm_script_run_in_context(this.#inner, contextifiedObject);
}
runInNewContext(contextObject: any, options: any) {
const context = createContext(contextObject);
return this.runInContext(context, options);
}
createCachedData() {
notImplemented("Script.prototype.createCachedData");
}
}
export function createContext(contextObject: any = {}, _options: any) {
if (isContext(contextObject)) {
return contextObject;
}
op_vm_create_context(contextObject);
return contextObject;
}
export function createScript(code: string, options: any) {
return new Script(code, options);
}
export function runInContext(
code: string,
contextifiedObject: any,
_options: any,
) {
return createScript(code).runInContext(contextifiedObject);
}
export function runInNewContext(
code: string,
contextObject: any,
options: any,
) {
if (options) {
console.warn("vm.runInNewContext options are currently not supported");
}
return createScript(code).runInNewContext(contextObject);
}
export function runInThisContext(
code: string,
options: any,
) {
return createScript(code, options).runInThisContext(options);
}
export function isContext(maybeContext: any) {
return op_vm_is_context(maybeContext);
}
export function compileFunction(_code: string, _params: any, _options: any) {
notImplemented("compileFunction");
}
export function measureMemory(_options: any) {
notImplemented("measureMemory");
}
export default {
Script,
createContext,
createScript,
runInContext,
runInNewContext,
runInThisContext,
isContext,
compileFunction,
measureMemory,
};

View file

@ -293,6 +293,7 @@ pub fn create_runtime_snapshot(
scope,
tmpl,
deno_node::ContextInitMode::ForSnapshot,
std::ptr::null_mut(),
);
assert_eq!(scope.add_context(ctx), deno_node::VM_CONTEXT_INDEX);
})),

View file

@ -669,8 +669,50 @@
"test-util-types-exists.js",
"test-util-types.js",
"test-util.js",
"test-vm-access-process-env.js",
"test-vm-attributes-property-not-on-sandbox.js",
"test-vm-codegen.js",
"test-vm-context-async-script.js",
"test-vm-context-property-forwarding.js",
"test-vm-create-and-run-in-context.js",
"test-vm-create-context-accessors.js",
"test-vm-create-context-arg.js",
"test-vm-create-context-circular-reference.js",
"test-vm-createcacheddata.js",
"test-vm-cross-context.js",
"test-vm-data-property-writable.js",
"test-vm-deleting-property.js",
"test-vm-function-declaration.js",
"test-vm-function-redefinition.js",
"test-vm-getters.js",
"test-vm-global-assignment.js",
"test-vm-global-define-property.js",
"test-vm-global-identity.js",
"test-vm-global-setter.js",
"test-vm-harmony-symbols.js",
"test-vm-indexed-properties.js",
"test-vm-inherited_properties.js",
"test-vm-is-context.js",
"test-vm-low-stack-space.js",
"test-vm-new-script-new-context.js",
"test-vm-new-script-this-context.js",
"test-vm-not-strict.js",
"test-vm-options-validation.js",
"test-vm-parse-abort-on-uncaught-exception.js",
"test-vm-preserves-property.js",
"test-vm-property-not-on-sandbox.js",
"test-vm-proxies.js",
"test-vm-proxy-failure-CP.js",
"test-vm-script-throw-in-tostring.js",
"test-vm-set-property-proxy.js",
"test-vm-set-proto-null-on-globalthis.js",
"test-vm-source-map-url.js",
"test-vm-static-this.js",
"test-vm-strict-mode.js",
"test-vm-symbols.js",
"test-vm-timeout-escape-promise-2.js",
"test-vm-timeout-escape-promise.js",
"test-vm-timeout.js",
"test-webcrypto-sign-verify.js",
"test-whatwg-encoding-custom-api-basics.js",
"test-whatwg-encoding-custom-textdecoder-ignorebom.js",
@ -716,7 +758,9 @@
"test-tty-stdout-end.js"
],
"pummel": [],
"sequential": ["test-child-process-exit.js"]
"sequential": [
"test-child-process-exit.js"
]
},
"windowsIgnore": {
"parallel": [
@ -744,7 +788,8 @@
"test-net-server-listen-path.js",
"test-net-socket-close-after-end.js",
"test-util-inspect-long-running.js",
"test-util-inspect.js"
"test-util-inspect.js",
"test-vm-low-stack-space.js"
]
},
"darwinIgnore": {

View file

@ -2622,39 +2622,14 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co
- [parallel/test-v8-version-tag.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-v8-version-tag.js)
- [parallel/test-validators.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-validators.js)
- [parallel/test-vfs.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vfs.js)
- [parallel/test-vm-access-process-env.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-access-process-env.js)
- [parallel/test-vm-api-handles-getter-errors.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-api-handles-getter-errors.js)
- [parallel/test-vm-attributes-property-not-on-sandbox.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-attributes-property-not-on-sandbox.js)
- [parallel/test-vm-basic.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-basic.js)
- [parallel/test-vm-cached-data.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-cached-data.js)
- [parallel/test-vm-codegen.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-codegen.js)
- [parallel/test-vm-context-async-script.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-context-async-script.js)
- [parallel/test-vm-context-property-forwarding.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-context-property-forwarding.js)
- [parallel/test-vm-context.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-context.js)
- [parallel/test-vm-create-and-run-in-context.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-create-and-run-in-context.js)
- [parallel/test-vm-create-context-accessors.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-create-context-accessors.js)
- [parallel/test-vm-create-context-arg.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-create-context-arg.js)
- [parallel/test-vm-create-context-circular-reference.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-create-context-circular-reference.js)
- [parallel/test-vm-createcacheddata.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-createcacheddata.js)
- [parallel/test-vm-cross-context.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-cross-context.js)
- [parallel/test-vm-data-property-writable.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-data-property-writable.js)
- [parallel/test-vm-deleting-property.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-deleting-property.js)
- [parallel/test-vm-dynamic-import-callback-missing-flag.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-dynamic-import-callback-missing-flag.js)
- [parallel/test-vm-function-declaration.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-function-declaration.js)
- [parallel/test-vm-function-redefinition.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-function-redefinition.js)
- [parallel/test-vm-getters.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-getters.js)
- [parallel/test-vm-global-assignment.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-global-assignment.js)
- [parallel/test-vm-global-define-property.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-global-define-property.js)
- [parallel/test-vm-global-get-own.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-global-get-own.js)
- [parallel/test-vm-global-identity.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-global-identity.js)
- [parallel/test-vm-global-non-writable-properties.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-global-non-writable-properties.js)
- [parallel/test-vm-global-property-interceptors.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-global-property-interceptors.js)
- [parallel/test-vm-global-setter.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-global-setter.js)
- [parallel/test-vm-harmony-symbols.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-harmony-symbols.js)
- [parallel/test-vm-indexed-properties.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-indexed-properties.js)
- [parallel/test-vm-inherited_properties.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-inherited_properties.js)
- [parallel/test-vm-is-context.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-is-context.js)
- [parallel/test-vm-low-stack-space.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-low-stack-space.js)
- [parallel/test-vm-measure-memory-lazy.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-measure-memory-lazy.js)
- [parallel/test-vm-measure-memory-multi-context.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-measure-memory-multi-context.js)
- [parallel/test-vm-measure-memory.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-measure-memory.js)
@ -2667,31 +2642,14 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co
- [parallel/test-vm-module-link.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-module-link.js)
- [parallel/test-vm-module-reevaluate.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-module-reevaluate.js)
- [parallel/test-vm-module-synthetic.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-module-synthetic.js)
- [parallel/test-vm-new-script-new-context.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-new-script-new-context.js)
- [parallel/test-vm-no-dynamic-import-callback.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-no-dynamic-import-callback.js)
- [parallel/test-vm-not-strict.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-not-strict.js)
- [parallel/test-vm-options-validation.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-options-validation.js)
- [parallel/test-vm-parse-abort-on-uncaught-exception.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-parse-abort-on-uncaught-exception.js)
- [parallel/test-vm-preserves-property.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-preserves-property.js)
- [parallel/test-vm-property-not-on-sandbox.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-property-not-on-sandbox.js)
- [parallel/test-vm-proxies.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-proxies.js)
- [parallel/test-vm-proxy-failure-CP.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-proxy-failure-CP.js)
- [parallel/test-vm-run-in-new-context.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-run-in-new-context.js)
- [parallel/test-vm-script-throw-in-tostring.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-script-throw-in-tostring.js)
- [parallel/test-vm-set-property-proxy.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-set-property-proxy.js)
- [parallel/test-vm-set-proto-null-on-globalthis.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-set-proto-null-on-globalthis.js)
- [parallel/test-vm-sigint-existing-handler.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-sigint-existing-handler.js)
- [parallel/test-vm-sigint.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-sigint.js)
- [parallel/test-vm-source-map-url.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-source-map-url.js)
- [parallel/test-vm-strict-assign.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-strict-assign.js)
- [parallel/test-vm-strict-mode.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-strict-mode.js)
- [parallel/test-vm-symbols.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-symbols.js)
- [parallel/test-vm-syntax-error-message.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-syntax-error-message.js)
- [parallel/test-vm-syntax-error-stderr.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-syntax-error-stderr.js)
- [parallel/test-vm-timeout-escape-promise-2.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-timeout-escape-promise-2.js)
- [parallel/test-vm-timeout-escape-promise-module.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-timeout-escape-promise-module.js)
- [parallel/test-vm-timeout-escape-promise.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-timeout-escape-promise.js)
- [parallel/test-vm-timeout.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-vm-timeout.js)
- [parallel/test-warn-sigprof.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-warn-sigprof.js)
- [parallel/test-warn-stream-wrap.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-warn-stream-wrap.js)
- [parallel/test-weakref.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-weakref.js)

View file

@ -45,6 +45,12 @@ const darwinIgnorePaths = new Set(
const decoder = new TextDecoder();
let testSerialId = 0;
function parseFlags(source: string): string[] {
const line = /^\/\/ Flags: (.+)$/um.exec(source);
if (line == null) return [];
return line[1].split(" ");
}
async function runTest(t: Deno.TestContext, path: string): Promise<void> {
// If filter patterns are given and any pattern doesn't match
// to the file path, then skip the case
@ -69,14 +75,23 @@ async function runTest(t: Deno.TestContext, path: string): Promise<void> {
const v8Flags = ["--stack-size=4000"];
const testSource = await Deno.readTextFile(testCase);
const envVars: Record<string, string> = {};
// TODO(kt3k): Parse `Flags` directive correctly
if (testSource.includes("Flags: --expose_externalize_string")) {
const knownGlobals: string[] = [];
parseFlags(testSource).forEach((flag) => {
switch (flag) {
case "--expose_externalize_string":
v8Flags.push("--expose-externalize-string");
// TODO(bartlomieju): disable verifying globals if that V8 flag is
// present. Even though we should be able to pass a list of globals
// that are allowed, it doesn't work, because the list is expected to
// contain actual JS objects, not strings :)).
envVars["NODE_TEST_KNOWN_GLOBALS"] = "0";
knownGlobals.push("createExternalizableString");
break;
case "--expose-gc":
v8Flags.push("--expose-gc");
knownGlobals.push("gc");
break;
default:
break;
}
});
if (knownGlobals.length > 0) {
envVars["NODE_TEST_KNOWN_GLOBALS"] = knownGlobals.join(",");
}
// TODO(nathanwhit): once we match node's behavior on executing
// `node:test` tests when we run a file, we can remove this

View file

@ -16,7 +16,6 @@ const path = require("path");
const util = require("util");
const tmpdir = require("./tmpdir");
function platformTimeout(ms) {
return ms;
}
@ -90,7 +89,7 @@ function allowGlobals(...allowlist) {
if (process.env.NODE_TEST_KNOWN_GLOBALS !== '0') {
if (process.env.NODE_TEST_KNOWN_GLOBALS) {
const knownFromEnv = process.env.NODE_TEST_KNOWN_GLOBALS.split(',');
const knownFromEnv = process.env.NODE_TEST_KNOWN_GLOBALS.split(',').map((name) => global[name]);
allowGlobals(...knownFromEnv);
}

View file

@ -0,0 +1,40 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
// Tests that node does neither crash nor throw an error when accessing
// process.env when inside a VM context.
// See https://github.com/nodejs/node-v0.x-archive/issues/7511.
require('../common');
const assert = require('assert');
const vm = require('vm');
const context = vm.createContext({ process });
const result = vm.runInContext('process.env["PATH"]', context);
assert.notStrictEqual(undefined, result);

View file

@ -0,0 +1,25 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
'use strict';
require('../common');
const assert = require('assert');
const vm = require('vm');
// Assert that accessor descriptors are not flattened on the sandbox.
// Issue: https://github.com/nodejs/node/issues/2734
const sandbox = {};
vm.createContext(sandbox);
const code = `Object.defineProperty(
this,
'foo',
{ get: function() {return 17} }
);
var desc = Object.getOwnPropertyDescriptor(this, 'foo');`;
vm.runInContext(code, sandbox);
assert.strictEqual(typeof sandbox.desc.get, 'function');

View file

@ -0,0 +1,108 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
'use strict';
require('../common');
const assert = require('assert');
const { createContext, runInContext, runInNewContext } = require('vm');
const WASM_BYTES = Buffer.from(
[0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00]);
{
const ctx = createContext({ WASM_BYTES });
const test = 'eval(""); new WebAssembly.Module(WASM_BYTES);';
runInContext(test, ctx);
runInNewContext(test, { WASM_BYTES }, {
contextCodeGeneration: undefined,
});
}
{
const ctx = createContext({}, {
codeGeneration: {
strings: false,
},
});
const EvalError = runInContext('EvalError', ctx);
assert.throws(() => {
runInContext('eval("x")', ctx);
}, EvalError);
}
{
const ctx = createContext({ WASM_BYTES }, {
codeGeneration: {
wasm: false,
},
});
const CompileError = runInContext('WebAssembly.CompileError', ctx);
assert.throws(() => {
runInContext('new WebAssembly.Module(WASM_BYTES)', ctx);
}, CompileError);
}
assert.throws(() => {
runInNewContext('eval("x")', {}, {
contextCodeGeneration: {
strings: false,
},
});
}, {
name: 'EvalError'
});
assert.throws(() => {
runInNewContext('new WebAssembly.Module(WASM_BYTES)', { WASM_BYTES }, {
contextCodeGeneration: {
wasm: false,
},
});
}, {
name: 'CompileError'
});
assert.throws(() => {
createContext({}, {
codeGeneration: {
strings: 0,
},
});
}, {
code: 'ERR_INVALID_ARG_TYPE',
});
assert.throws(() => {
runInNewContext('eval("x")', {}, {
contextCodeGeneration: {
wasm: 1,
},
});
}, {
code: 'ERR_INVALID_ARG_TYPE'
});
assert.throws(() => {
createContext({}, {
codeGeneration: 1,
});
}, {
code: 'ERR_INVALID_ARG_TYPE',
});
assert.throws(() => {
createContext({}, {
codeGeneration: null,
});
}, {
code: 'ERR_INVALID_ARG_TYPE',
});

View file

@ -0,0 +1,42 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
const common = require('../common');
const assert = require('assert');
const vm = require('vm');
const sandbox = { setTimeout };
const ctx = vm.createContext(sandbox);
vm.runInContext('setTimeout(function() { x = 3; }, 0);', ctx);
setTimeout(common.mustCall(() => {
assert.strictEqual(sandbox.x, 3);
assert.strictEqual(ctx.x, 3);
}), 1);

View file

@ -0,0 +1,72 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
require('../common');
const assert = require('assert');
const vm = require('vm');
const sandbox = { x: 3 };
const ctx = vm.createContext(sandbox);
assert.strictEqual(vm.runInContext('x;', ctx), 3);
vm.runInContext('y = 4;', ctx);
assert.strictEqual(sandbox.y, 4);
assert.strictEqual(ctx.y, 4);
// Test `IndexedPropertyGetterCallback` and `IndexedPropertyDeleterCallback`
const x = { get 1() { return 5; } };
const pd_expected = Object.getOwnPropertyDescriptor(x, 1);
const ctx2 = vm.createContext(x);
const pd_actual = Object.getOwnPropertyDescriptor(ctx2, 1);
assert.deepStrictEqual(pd_actual, pd_expected);
assert.strictEqual(ctx2[1], 5);
delete ctx2[1];
assert.strictEqual(ctx2[1], undefined);
// https://github.com/nodejs/node/issues/33806
{
const ctx = vm.createContext();
Object.defineProperty(ctx, 'prop', {
get() {
return undefined;
},
set(val) {
throw new Error('test error');
},
});
assert.throws(() => {
vm.runInContext('prop = 42', ctx);
}, {
message: 'test error',
});
}

View file

@ -0,0 +1,57 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
// Flags: --expose-gc
require('../common');
const assert = require('assert');
const vm = require('vm');
// Run in a new empty context
let context = vm.createContext();
let result = vm.runInContext('"passed";', context);
assert.strictEqual(result, 'passed');
// Create a new pre-populated context
context = vm.createContext({ 'foo': 'bar', 'thing': 'lala' });
assert.strictEqual(context.foo, 'bar');
assert.strictEqual(context.thing, 'lala');
// Test updating context
result = vm.runInContext('var foo = 3;', context);
assert.strictEqual(context.foo, 3);
assert.strictEqual(context.thing, 'lala');
// https://github.com/nodejs/node/issues/5768
// Run in contextified sandbox without referencing the context
const sandbox = { x: 1 };
vm.createContext(sandbox);
global.gc();
vm.runInContext('x = 2', sandbox);
// Should not crash.

View file

@ -0,0 +1,56 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
require('../common');
const assert = require('assert');
const vm = require('vm');
let ctx = {};
Object.defineProperty(ctx, 'getter', {
get: function() {
return 'ok';
}
});
let val;
Object.defineProperty(ctx, 'setter', {
set: function(_val) {
val = _val;
},
get: function() {
return `ok=${val}`;
}
});
ctx = vm.createContext(ctx);
const result = vm.runInContext('setter = "test";[getter,setter]', ctx);
assert.strictEqual(result[0], 'ok');
assert.strictEqual(result[1], 'ok=test');

View file

@ -0,0 +1,47 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
require('../common');
const assert = require('assert');
const vm = require('vm');
assert.throws(() => {
vm.createContext('string is not supported');
}, {
code: 'ERR_INVALID_ARG_TYPE',
name: 'TypeError'
});
// Should not throw.
vm.createContext({ a: 1 });
vm.createContext([0, 1, 2, 3]);
const sandbox = {};
vm.createContext(sandbox);
vm.createContext(sandbox);

View file

@ -0,0 +1,41 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
require('../common');
const assert = require('assert');
const vm = require('vm');
let sbx = {};
sbx.window = sbx;
sbx = vm.createContext(sbx);
sbx.test = 123;
assert.strictEqual(sbx.window.window.window.window.window.test, 123);

View file

@ -0,0 +1,29 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
'use strict';
require('../common');
const { Script } = require('vm');
const assert = require('assert');
const source = 'function x() {} const y = x();';
const script = new Script(source);
let cachedData = script.createCachedData();
assert(cachedData instanceof Buffer);
assert(!new Script(source, { cachedData }).cachedDataRejected);
script.runInNewContext();
for (let i = 0; i < 10; i += 1) {
cachedData = script.createCachedData();
assert(!new Script(source, { cachedData }).cachedDataRejected);
}

View file

@ -0,0 +1,36 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
require('../common');
const vm = require('vm');
const ctx = vm.createContext(global);
// Should not throw.
vm.runInContext('!function() { var x = console.log; }()', ctx);

View file

@ -0,0 +1,35 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
'use strict';
// Refs: https://github.com/nodejs/node/issues/10223
require('../common');
const vm = require('vm');
const assert = require('assert');
const context = vm.createContext({});
let code = `
Object.defineProperty(this, 'foo', {value: 5});
Object.getOwnPropertyDescriptor(this, 'foo');
`;
let desc = vm.runInContext(code, context);
assert.strictEqual(desc.writable, false);
// Check that interceptors work for symbols.
code = `
const bar = Symbol('bar');
Object.defineProperty(this, bar, {value: 6});
Object.getOwnPropertyDescriptor(this, bar);
`;
desc = vm.runInContext(code, context);
assert.strictEqual(desc.value, 6);

View file

@ -0,0 +1,22 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
'use strict';
// Refs: https://github.com/nodejs/node/issues/6287
require('../common');
const assert = require('assert');
const vm = require('vm');
const context = vm.createContext();
const res = vm.runInContext(`
this.x = 'prop';
delete this.x;
Object.getOwnPropertyDescriptor(this, 'x');
`, context);
assert.strictEqual(res, undefined);

View file

@ -0,0 +1,56 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
require('../common');
const assert = require('assert');
const vm = require('vm');
const o = vm.createContext({ console });
// Function declaration and expression should both be copied to the
// sandboxed context.
let code = 'let a = function() {};\n';
code += 'function b(){}\n';
code += 'var c = function() {};\n';
code += 'var d = () => {};\n';
code += 'let e = () => {};\n';
// Grab the global b function as the completion value, to ensure that
// we are getting the global function, and not some other thing
code += '(function(){return this})().b;\n';
const res = vm.runInContext(code, o, 'test');
assert.strictEqual(typeof res, 'function');
assert.strictEqual(res.name, 'b');
assert.strictEqual(typeof o.a, 'undefined');
assert.strictEqual(typeof o.b, 'function');
assert.strictEqual(typeof o.c, 'function');
assert.strictEqual(typeof o.d, 'function');
assert.strictEqual(typeof o.e, 'undefined');
assert.strictEqual(res, o.b);

View file

@ -0,0 +1,18 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
'use strict';
// Refs: https://github.com/nodejs/node/issues/548
require('../common');
const assert = require('assert');
const vm = require('vm');
const context = vm.createContext();
vm.runInContext('function test() { return 0; }', context);
vm.runInContext('function test() { return 1; }', context);
const result = vm.runInContext('test()', context);
assert.strictEqual(result, 1);

View file

@ -0,0 +1,31 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
'use strict';
// Refs: https://github.com/nodejs/node/issues/2734
require('../common');
const assert = require('assert');
const vm = require('vm');
const sandbox = {};
Object.defineProperty(sandbox, 'prop', {
get() {
return 'foo';
}
});
const descriptor = Object.getOwnPropertyDescriptor(sandbox, 'prop');
const context = vm.createContext(sandbox);
const code = 'Object.getOwnPropertyDescriptor(this, "prop");';
const result = vm.runInContext(code, context);
// Ref: https://github.com/nodejs/node/issues/11803
assert.deepStrictEqual(Object.keys(result), Object.keys(descriptor));
for (const prop of Object.keys(result)) {
assert.strictEqual(result[prop], descriptor[prop]);
}

View file

@ -0,0 +1,22 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
'use strict';
// Regression test for https://github.com/nodejs/node/issues/10806
require('../common');
const assert = require('assert');
const vm = require('vm');
const ctx = vm.createContext({ open() { } });
const window = vm.runInContext('this', ctx);
const other = 123;
assert.notStrictEqual(window.open, other);
window.open = other;
assert.strictEqual(window.open, other);
window.open = other;
assert.strictEqual(window.open, other);

View file

@ -0,0 +1,54 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
require('../common');
const assert = require('assert');
const vm = require('vm');
const code =
'Object.defineProperty(this, "f", {\n' +
' get: function() { return x; },\n' +
' set: function(k) { x = k; },\n' +
' configurable: true,\n' +
' enumerable: true\n' +
'});\n' +
'g = f;\n' +
'f;\n';
const x = {};
const o = vm.createContext({ console, x });
const res = vm.runInContext(code, o, 'test');
assert(res);
assert.strictEqual(typeof res, 'object');
assert.strictEqual(res, x);
assert.strictEqual(o.f, res);
assert.deepStrictEqual(Object.keys(o), ['console', 'x', 'f', 'g']);

View file

@ -0,0 +1,39 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
require('../common');
const assert = require('assert');
const vm = require('vm');
const ctx = vm.createContext();
ctx.window = ctx;
const thisVal = vm.runInContext('this;', ctx);
const windowVal = vm.runInContext('window;', ctx);
assert.strictEqual(thisVal, windowVal);

View file

@ -0,0 +1,168 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
'use strict';
const common = require('../common');
const assert = require('assert');
const vm = require('vm');
const getSetSymbolReceivingFunction = Symbol('sym-1');
const getSetSymbolReceivingNumber = Symbol('sym-2');
const symbolReceivingNumber = Symbol('sym-3');
const unknownSymbolReceivingNumber = Symbol('sym-4');
const window = createWindow();
const descriptor1 = Object.getOwnPropertyDescriptor(
window.globalProxy,
'getSetPropReceivingFunction'
);
assert.strictEqual(typeof descriptor1.get, 'function');
assert.strictEqual(typeof descriptor1.set, 'function');
assert.strictEqual(descriptor1.configurable, true);
const descriptor2 = Object.getOwnPropertyDescriptor(
window.globalProxy,
'getSetPropReceivingNumber'
);
assert.strictEqual(typeof descriptor2.get, 'function');
assert.strictEqual(typeof descriptor2.set, 'function');
assert.strictEqual(descriptor2.configurable, true);
const descriptor3 = Object.getOwnPropertyDescriptor(
window.globalProxy,
'propReceivingNumber'
);
assert.strictEqual(descriptor3.value, 44);
const descriptor4 = Object.getOwnPropertyDescriptor(
window.globalProxy,
'unknownPropReceivingNumber'
);
assert.strictEqual(descriptor4, undefined);
const descriptor5 = Object.getOwnPropertyDescriptor(
window.globalProxy,
getSetSymbolReceivingFunction
);
assert.strictEqual(typeof descriptor5.get, 'function');
assert.strictEqual(typeof descriptor5.set, 'function');
assert.strictEqual(descriptor5.configurable, true);
const descriptor6 = Object.getOwnPropertyDescriptor(
window.globalProxy,
getSetSymbolReceivingNumber
);
assert.strictEqual(typeof descriptor6.get, 'function');
assert.strictEqual(typeof descriptor6.set, 'function');
assert.strictEqual(descriptor6.configurable, true);
const descriptor7 = Object.getOwnPropertyDescriptor(
window.globalProxy,
symbolReceivingNumber
);
assert.strictEqual(descriptor7.value, 48);
const descriptor8 = Object.getOwnPropertyDescriptor(
window.globalProxy,
unknownSymbolReceivingNumber
);
assert.strictEqual(descriptor8, undefined);
const descriptor9 = Object.getOwnPropertyDescriptor(
window.globalProxy,
'getSetPropThrowing'
);
assert.strictEqual(typeof descriptor9.get, 'function');
assert.strictEqual(typeof descriptor9.set, 'function');
assert.strictEqual(descriptor9.configurable, true);
const descriptor10 = Object.getOwnPropertyDescriptor(
window.globalProxy,
'nonWritableProp'
);
assert.strictEqual(descriptor10.value, 51);
assert.strictEqual(descriptor10.writable, false);
// Regression test for GH-42962. This assignment should not throw.
window.globalProxy.getSetPropReceivingFunction = () => {};
assert.strictEqual(window.globalProxy.getSetPropReceivingFunction, 42);
window.globalProxy.getSetPropReceivingNumber = 143;
assert.strictEqual(window.globalProxy.getSetPropReceivingNumber, 43);
window.globalProxy.propReceivingNumber = 144;
assert.strictEqual(window.globalProxy.propReceivingNumber, 144);
window.globalProxy.unknownPropReceivingNumber = 145;
assert.strictEqual(window.globalProxy.unknownPropReceivingNumber, 145);
window.globalProxy[getSetSymbolReceivingFunction] = () => {};
assert.strictEqual(window.globalProxy[getSetSymbolReceivingFunction], 46);
window.globalProxy[getSetSymbolReceivingNumber] = 147;
assert.strictEqual(window.globalProxy[getSetSymbolReceivingNumber], 47);
window.globalProxy[symbolReceivingNumber] = 148;
assert.strictEqual(window.globalProxy[symbolReceivingNumber], 148);
window.globalProxy[unknownSymbolReceivingNumber] = 149;
assert.strictEqual(window.globalProxy[unknownSymbolReceivingNumber], 149);
assert.throws(
() => (window.globalProxy.getSetPropThrowing = 150),
new Error('setter called')
);
assert.strictEqual(window.globalProxy.getSetPropThrowing, 50);
assert.throws(
() => (window.globalProxy.nonWritableProp = 151),
new TypeError('Cannot redefine property: nonWritableProp')
);
assert.strictEqual(window.globalProxy.nonWritableProp, 51);
function createWindow() {
const obj = {};
vm.createContext(obj);
Object.defineProperty(obj, 'getSetPropReceivingFunction', {
get: common.mustCall(() => 42),
set: common.mustCall(),
configurable: true,
});
Object.defineProperty(obj, 'getSetPropReceivingNumber', {
get: common.mustCall(() => 43),
set: common.mustCall(),
configurable: true,
});
obj.propReceivingNumber = 44;
Object.defineProperty(obj, getSetSymbolReceivingFunction, {
get: common.mustCall(() => 46),
set: common.mustCall(),
configurable: true,
});
Object.defineProperty(obj, getSetSymbolReceivingNumber, {
get: common.mustCall(() => 47),
set: common.mustCall(),
configurable: true,
});
obj[symbolReceivingNumber] = 48;
Object.defineProperty(obj, 'getSetPropThrowing', {
get: common.mustCall(() => 50),
set: common.mustCall(() => {
throw new Error('setter called');
}),
configurable: true,
});
Object.defineProperty(obj, 'nonWritableProp', {
value: 51,
writable: false,
});
obj.globalProxy = vm.runInContext('this', obj);
return obj;
}

View file

@ -0,0 +1,44 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
require('../common');
const assert = require('assert');
const vm = require('vm');
// The sandbox should have its own Symbol constructor.
let sandbox = {};
vm.runInNewContext('this.Symbol = Symbol', sandbox);
assert.strictEqual(typeof sandbox.Symbol, 'function');
assert.notStrictEqual(sandbox.Symbol, Symbol);
// Unless we copy the Symbol constructor explicitly, of course.
sandbox = { Symbol };
vm.runInNewContext('this.Symbol = Symbol', sandbox);
assert.strictEqual(typeof sandbox.Symbol, 'function');
assert.strictEqual(sandbox.Symbol, Symbol);

View file

@ -0,0 +1,24 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
'use strict';
require('../common');
const assert = require('assert');
const vm = require('vm');
const code = `Object.defineProperty(this, 99, {
value: 20,
enumerable: true
});`;
const sandbox = {};
const ctx = vm.createContext(sandbox);
vm.runInContext(code, ctx);
assert.strictEqual(sandbox[99], 20);

View file

@ -0,0 +1,45 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
'use strict';
require('../common');
const vm = require('vm');
const assert = require('assert');
let base = {
propBase: 1
};
let sandbox = Object.create(base, {
propSandbox: { value: 3 }
});
const context = vm.createContext(sandbox);
let result = vm.runInContext('Object.hasOwnProperty(this, "propBase");',
context);
assert.strictEqual(result, false);
// Ref: https://github.com/nodejs/node/issues/5350
base = { __proto__: null };
base.x = 1;
base.y = 2;
sandbox = { __proto__: base };
sandbox.z = 3;
assert.deepStrictEqual(Object.keys(sandbox), ['z']);
const code = 'x = 0; z = 4;';
result = vm.runInNewContext(code, sandbox);
assert.strictEqual(result, 4);
// Check that y is not an own property.
assert.deepStrictEqual(Object.keys(sandbox), ['z', 'x']);

View file

@ -0,0 +1,53 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
require('../common');
const assert = require('assert');
const vm = require('vm');
for (const valToTest of [
'string', null, undefined, 8.9, Symbol('sym'), true,
]) {
assert.throws(() => {
vm.isContext(valToTest);
}, {
code: 'ERR_INVALID_ARG_TYPE',
name: 'TypeError'
});
}
assert.strictEqual(vm.isContext({}), false);
assert.strictEqual(vm.isContext([]), false);
assert.strictEqual(vm.isContext(vm.createContext()), true);
assert.strictEqual(vm.isContext(vm.createContext([])), true);
const sandbox = { foo: 'bar' };
vm.createContext(sandbox);
assert.strictEqual(vm.isContext(sandbox), true);

View file

@ -0,0 +1,33 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
'use strict';
require('../common');
const assert = require('assert');
const vm = require('vm');
function a() {
try {
return a();
} catch {
// Throw an exception as near to the recursion-based RangeError as possible.
return vm.runInThisContext('() => 42')();
}
}
assert.strictEqual(a(), 42);
function b() {
try {
return b();
} catch {
// This writes a lot of noise to stderr, but it still works.
return vm.runInNewContext('() => 42')();
}
}
assert.strictEqual(b(), 42);

View file

@ -0,0 +1,114 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
require('../common');
const assert = require('assert');
const Script = require('vm').Script;
{
const script = new Script('\'passed\';');
const result1 = script.runInNewContext();
const result2 = script.runInNewContext();
assert.strictEqual(result1, 'passed');
assert.strictEqual(result2, 'passed');
}
{
const script = new Script('throw new Error(\'test\');');
assert.throws(() => {
script.runInNewContext();
}, /^Error: test$/);
}
{
const script = new Script('foo.bar = 5;');
assert.throws(() => {
script.runInNewContext();
}, /^ReferenceError: foo is not defined$/);
}
{
global.hello = 5;
const script = new Script('hello = 2');
script.runInNewContext();
assert.strictEqual(global.hello, 5);
// Cleanup
delete global.hello;
}
{
global.code = 'foo = 1;' +
'bar = 2;' +
'if (baz !== 3) throw new Error(\'test fail\');';
global.foo = 2;
global.obj = { foo: 0, baz: 3 };
const script = new Script(global.code);
/* eslint-disable no-unused-vars */
const baz = script.runInNewContext(global.obj);
/* eslint-enable no-unused-vars */
assert.strictEqual(global.obj.foo, 1);
assert.strictEqual(global.obj.bar, 2);
assert.strictEqual(global.foo, 2);
// cleanup
delete global.code;
delete global.foo;
delete global.obj;
}
{
const script = new Script('f()');
function changeFoo() { global.foo = 100; }
script.runInNewContext({ f: changeFoo });
assert.strictEqual(global.foo, 100);
// cleanup
delete global.foo;
}
{
const script = new Script('f.a = 2');
const f = { a: 1 };
script.runInNewContext({ f });
assert.strictEqual(f.a, 2);
assert.throws(() => {
script.runInNewContext();
}, /^ReferenceError: f is not defined$/);
}
{
const script = new Script('');
assert.throws(() => {
script.runInNewContext.call('\'hello\';');
}, /^TypeError: this\.runInContext is not a function$/);
}

View file

@ -0,0 +1,44 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
/* eslint-disable strict, no-var, no-delete-var, no-undef, node-core/required-modules, node-core/require-common-first */
// Importing common would break the execution. Indeed running `vm.runInThisContext` alters the global context
// when declaring new variables with `var`. The other rules (strict, no-var, no-delete-var) have been disabled
// in order to be able to test this specific not-strict case playing with `var` and `delete`.
// Related to bug report: https://github.com/nodejs/node/issues/43129
var assert = require('assert');
var vm = require('vm');
var data = [];
var a = 'direct';
delete a;
data.push(a);
var item2 = vm.runInThisContext(`
var unusedB = 1;
var data = [];
var b = "this";
delete b;
data.push(b);
data[0]
`);
data.push(item2);
vm.runInContext(
`
var unusedC = 1;
var c = "new";
delete c;
data.push(c);
`,
vm.createContext({ data: data })
);
assert.deepStrictEqual(data, ['direct', 'this', 'new']);
assert.strictEqual(typeof unusedB, 'number'); // Declared within runInThisContext
assert.strictEqual(typeof unusedC, 'undefined'); // Declared within runInContext

View file

@ -0,0 +1,101 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
'use strict';
require('../common');
const assert = require('assert');
const vm = require('vm');
const invalidArgType = {
name: 'TypeError',
code: 'ERR_INVALID_ARG_TYPE'
};
const outOfRange = {
name: 'RangeError',
code: 'ERR_OUT_OF_RANGE'
};
assert.throws(() => {
new vm.Script('void 0', 42);
}, invalidArgType);
[null, {}, [1], 'bad', true].forEach((value) => {
assert.throws(() => {
new vm.Script('void 0', { lineOffset: value });
}, invalidArgType);
assert.throws(() => {
new vm.Script('void 0', { columnOffset: value });
}, invalidArgType);
});
[0.1, 2 ** 32].forEach((value) => {
assert.throws(() => {
new vm.Script('void 0', { lineOffset: value });
}, outOfRange);
assert.throws(() => {
new vm.Script('void 0', { columnOffset: value });
}, outOfRange);
});
assert.throws(() => {
new vm.Script('void 0', { lineOffset: Number.MAX_SAFE_INTEGER });
}, outOfRange);
assert.throws(() => {
new vm.Script('void 0', { columnOffset: Number.MAX_SAFE_INTEGER });
}, outOfRange);
assert.throws(() => {
new vm.Script('void 0', { filename: 123 });
}, invalidArgType);
assert.throws(() => {
new vm.Script('void 0', { produceCachedData: 1 });
}, invalidArgType);
[[0], {}, true, 'bad', 42].forEach((value) => {
assert.throws(() => {
new vm.Script('void 0', { cachedData: value });
}, invalidArgType);
});
{
const script = new vm.Script('void 0');
const sandbox = vm.createContext();
function assertErrors(options, errCheck) {
assert.throws(() => {
script.runInThisContext(options);
}, errCheck);
assert.throws(() => {
script.runInContext(sandbox, options);
}, errCheck);
assert.throws(() => {
script.runInNewContext({}, options);
}, errCheck);
}
[null, 'bad', 42].forEach((value) => {
assertErrors(value, invalidArgType);
});
[{}, [1], 'bad', null].forEach((value) => {
assertErrors({ timeout: value }, invalidArgType);
});
[-1, 0, NaN].forEach((value) => {
assertErrors({ timeout: value }, outOfRange);
});
[{}, [1], 'bad', 1, null].forEach((value) => {
assertErrors({ displayErrors: value }, invalidArgType);
assertErrors({ breakOnSigint: value }, invalidArgType);
});
}

View file

@ -0,0 +1,25 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
// Flags: --abort-on-uncaught-exception
'use strict';
require('../common');
const vm = require('vm');
// Regression test for https://github.com/nodejs/node/issues/13258
try {
new vm.Script({ toString() { throw new Error('foo'); } }, {});
} catch {
// Continue regardless of error.
}
try {
new vm.Script('[', {});
} catch {
// Continue regardless of error.
}

View file

@ -0,0 +1,32 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
'use strict';
require('../common');
const assert = require('assert');
const vm = require('vm');
const x = {};
Object.defineProperty(x, 'prop', {
configurable: false,
enumerable: false,
writable: false,
value: 'val'
});
const o = vm.createContext(x);
const code = 'Object.getOwnPropertyDescriptor(this, "prop")';
const res = vm.runInContext(code, o, 'test');
assert(res);
assert.strictEqual(typeof res, 'object');
assert.strictEqual(res.value, 'val');
assert.strictEqual(res.configurable, false);
assert.strictEqual(res.enumerable, false);
assert.strictEqual(res.writable, false);

View file

@ -0,0 +1,44 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
'use strict';
require('../common');
const assert = require('assert');
const vm = require('vm');
// This, admittedly contrived, example tests an edge cases of the vm module.
//
// The GetterCallback explicitly checks the global_proxy() if a property is
// not found on the sandbox. In the following test, the explicit check
// inside the callback yields different results than deferring the
// check until after the callback. The check is deferred if the
// callback does not intercept, i.e., if args.GetReturnValue().Set() is
// not called.
// Check that the GetterCallback explicitly calls GetRealNamedProperty()
// on the global proxy if the property is not found on the sandbox.
//
// foo is not defined on the sandbox until we call CopyProperties().
// In the GetterCallback, we do not find the property on the sandbox and
// get the property from the global proxy. Since the return value is
// the sandbox, we replace it by
// the global_proxy to keep the correct identities.
//
// This test case is partially inspired by
// https://github.com/nodejs/node/issues/855
const sandbox = { console };
sandbox.document = { defaultView: sandbox };
vm.createContext(sandbox);
const code = `Object.defineProperty(
this,
'foo',
{ get: function() {return document.defaultView} }
);
var result = foo === this;`;
vm.runInContext(code, sandbox);
assert.strictEqual(sandbox.result, true);

View file

@ -0,0 +1,25 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
'use strict';
require('../common');
const assert = require('assert');
const vm = require('vm');
// src/node_contextify.cc filters out the Proxy object from the parent
// context. Make sure that the new context has a Proxy object of its own.
let sandbox = {};
vm.runInNewContext('this.Proxy = Proxy', sandbox);
assert.strictEqual(typeof sandbox.Proxy, 'function');
assert.notStrictEqual(sandbox.Proxy, Proxy);
// Unless we copy the Proxy object explicitly, of course.
sandbox = { Proxy };
vm.runInNewContext('this.Proxy = Proxy', sandbox);
assert.strictEqual(typeof sandbox.Proxy, 'function');
assert.strictEqual(sandbox.Proxy, Proxy);

View file

@ -0,0 +1,22 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
'use strict';
require('../common');
const vm = require('vm');
// Check that we do not accidentally query attributes.
// Issue: https://github.com/nodejs/node/issues/11902
const handler = {
getOwnPropertyDescriptor: (target, prop) => {
throw new Error('whoops');
}
};
const sandbox = new Proxy({ foo: 'bar' }, handler);
const context = vm.createContext(sandbox);
vm.runInContext('', context);

View file

@ -0,0 +1,21 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
'use strict';
require('../common');
const assert = require('assert');
const vm = require('vm');
assert.throws(() => {
new vm.Script({
toString() {
throw new Error();
}
});
}, Error);

View file

@ -0,0 +1,23 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
'use strict';
const common = require('../common');
const assert = require('assert');
const vm = require('vm');
// Regression test for https://github.com/nodejs/node/issues/34606
const handler = {
getOwnPropertyDescriptor: common.mustCallAtLeast(() => {
return {};
})
};
const proxy = new Proxy({}, handler);
assert.throws(() => vm.runInNewContext('p = 6', proxy),
/getOwnPropertyDescriptor/);

View file

@ -0,0 +1,20 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
'use strict';
require('../common');
// Setting __proto__ on vm context's globalThis should not cause a crash
// Regression test for https://github.com/nodejs/node/issues/47798
const vm = require('vm');
const context = vm.createContext();
const contextGlobalThis = vm.runInContext('this', context);
// Should not crash.
contextGlobalThis.__proto__ = null; // eslint-disable-line no-proto

View file

@ -0,0 +1,34 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
'use strict';
require('../common');
const assert = require('assert');
const vm = require('vm');
function checkSourceMapUrl(source, expectedSourceMapURL) {
const script = new vm.Script(source);
assert.strictEqual(script.sourceMapURL, expectedSourceMapURL);
}
// No magic comment
checkSourceMapUrl(`
function myFunc() {}
`, undefined);
// Malformed magic comment
checkSourceMapUrl(`
function myFunc() {}
// sourceMappingURL=sourcemap.json
`, undefined);
// Expected magic comment
checkSourceMapUrl(`
function myFunc() {}
//# sourceMappingURL=sourcemap.json
`, 'sourcemap.json');

View file

@ -0,0 +1,21 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
'use strict';
// https://github.com/nodejs/node/issues/12300
require('../common');
const assert = require('assert');
const vm = require('vm');
const ctx = vm.createContext({ x: 42 });
// This might look as if x has not been declared, but x is defined on the
// sandbox and the assignment should not throw.
vm.runInContext('"use strict"; x = 1', ctx);
assert.strictEqual(ctx.x, 1);

View file

@ -0,0 +1,30 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
'use strict';
require('../common');
const assert = require('assert');
const vm = require('vm');
const symbol = Symbol();
function Document() {
this[symbol] = 'foo';
}
Document.prototype.getSymbolValue = function() {
return this[symbol];
};
const context = new Document();
vm.createContext(context);
assert.strictEqual(context.getSymbolValue(), 'foo');
assert.strictEqual(vm.runInContext('this.getSymbolValue()', context), 'foo');

View file

@ -0,0 +1,45 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
'use strict';
// https://github.com/nodejs/node/issues/3020
// Promises used to allow code to escape the timeout
// set for runInContext, runInNewContext, and runInThisContext.
require('../common');
const assert = require('assert');
const vm = require('vm');
const NS_PER_MS = 1000000n;
const hrtime = process.hrtime.bigint;
function loop() {
const start = hrtime();
while (1) {
const current = hrtime();
const span = (current - start) / NS_PER_MS;
if (span >= 2000n) {
throw new Error(
`escaped timeout at ${span} milliseconds!`);
}
}
}
assert.throws(() => {
vm.runInNewContext(
'Promise.resolve().then(() => loop());',
{
hrtime,
loop
},
{ timeout: 10, microtaskMode: 'afterEvaluate' }
);
}, {
code: 'ERR_SCRIPT_EXECUTION_TIMEOUT',
message: 'Script execution timed out after 10ms'
});

View file

@ -0,0 +1,46 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
'use strict';
// https://github.com/nodejs/node/issues/3020
// Promises used to allow code to escape the timeout
// set for runInContext, runInNewContext, and runInThisContext.
require('../common');
const assert = require('assert');
const vm = require('vm');
const NS_PER_MS = 1000000n;
const hrtime = process.hrtime.bigint;
function loop() {
const start = hrtime();
while (1) {
const current = hrtime();
const span = (current - start) / NS_PER_MS;
if (span >= 2000n) {
throw new Error(
`escaped timeout at ${span} milliseconds!`);
}
}
}
assert.throws(() => {
vm.runInNewContext(
'Promise.resolve().then(() => loop()); loop();',
{
hrtime,
loop
},
{ timeout: 5, microtaskMode: 'afterEvaluate' }
);
}, {
code: 'ERR_SCRIPT_EXECUTION_TIMEOUT',
message: 'Script execution timed out after 5ms'
});

View file

@ -0,0 +1,88 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
require('../common');
const assert = require('assert');
const vm = require('vm');
// Timeout of 100ms executing endless loop
assert.throws(
function() {
vm.runInThisContext('while(true) {}', { timeout: 100 });
},
{
code: 'ERR_SCRIPT_EXECUTION_TIMEOUT',
message: 'Script execution timed out after 100ms'
});
// Timeout of 1000ms, script finishes first
vm.runInThisContext('', { timeout: 1000 });
// Nested vm timeouts, inner timeout propagates out
assert.throws(
function() {
const context = {
log: console.log,
runInVM: function(timeout) {
vm.runInNewContext('while(true) {}', context, { timeout });
}
};
vm.runInNewContext('runInVM(10)', context, { timeout: 10000 });
throw new Error('Test 5 failed');
},
{
code: 'ERR_SCRIPT_EXECUTION_TIMEOUT',
message: 'Script execution timed out after 10ms'
});
// Nested vm timeouts, outer timeout is shorter and fires first.
assert.throws(
function() {
const context = {
runInVM: function(timeout) {
vm.runInNewContext('while(true) {}', context, { timeout });
}
};
vm.runInNewContext('runInVM(10000)', context, { timeout: 100 });
throw new Error('Test 6 failed');
},
{
code: 'ERR_SCRIPT_EXECUTION_TIMEOUT',
message: 'Script execution timed out after 100ms'
});
// Nested vm timeouts, inner script throws an error.
assert.throws(function() {
const context = {
runInVM: function(timeout) {
vm.runInNewContext('throw new Error(\'foobar\')', context, { timeout });
}
};
vm.runInNewContext('runInVM(10000)', context, { timeout: 100000 });
}, /foobar/);

View file

@ -128,7 +128,7 @@ Deno.test({
const obj = {};
assertEquals(isContext(obj), false);
assertEquals(isContext(globalThis), false);
const sandbox = runInNewContext("{}");
const sandbox = runInNewContext("({})");
assertEquals(isContext(sandbox), false);
},
});