You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					278 lines
				
				9.9 KiB
			
		
		
			
		
	
	
					278 lines
				
				9.9 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								import { EventEmitter } from 'events';
							 | 
						||
| 
								 | 
							
								import fs from 'fs';
							 | 
						||
| 
								 | 
							
								import pa from 'path';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Interface for nodes fs module
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								export interface VMFS {
							 | 
						||
| 
								 | 
							
								  /** Implements fs.statSync */
							 | 
						||
| 
								 | 
							
								  statSync: typeof fs.statSync;
							 | 
						||
| 
								 | 
							
								  /** Implements fs.readFileSync */
							 | 
						||
| 
								 | 
							
								  readFileSync: typeof fs.readFileSync;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Interface for nodes path module
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								export interface VMPath {
							 | 
						||
| 
								 | 
							
								  /** Implements path.resolve */
							 | 
						||
| 
								 | 
							
								  resolve: typeof pa.resolve;
							 | 
						||
| 
								 | 
							
								  /** Implements path.isAbsolute */
							 | 
						||
| 
								 | 
							
								  isAbsolute: typeof pa.isAbsolute;
							 | 
						||
| 
								 | 
							
								  /** Implements path.join */
							 | 
						||
| 
								 | 
							
								  join: typeof pa.join;
							 | 
						||
| 
								 | 
							
								  /** Implements path.basename */
							 | 
						||
| 
								 | 
							
								  basename: typeof pa.basename;
							 | 
						||
| 
								 | 
							
								  /** Implements path.dirname */
							 | 
						||
| 
								 | 
							
								  dirname: typeof pa.dirname;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Custom file system which abstracts functions from node's fs and path modules.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								export interface VMFileSystemInterface extends VMFS, VMPath {
							 | 
						||
| 
								 | 
							
								  /** Implements (sep) => sep === path.sep */
							 | 
						||
| 
								 | 
							
								  isSeparator(char: string): boolean;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Implementation of a default file system.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								export class VMFileSystem implements VMFileSystemInterface {
							 | 
						||
| 
								 | 
							
								  constructor(options?: { fs?: VMFS, path?: VMPath });
							 | 
						||
| 
								 | 
							
								  /** Implements fs.statSync */
							 | 
						||
| 
								 | 
							
								  statSync: typeof fs.statSync;
							 | 
						||
| 
								 | 
							
								  /** Implements fs.readFileSync */
							 | 
						||
| 
								 | 
							
								  readFileSync: typeof fs.readFileSync;
							 | 
						||
| 
								 | 
							
								  /** Implements path.resolve */
							 | 
						||
| 
								 | 
							
								  resolve: typeof pa.resolve;
							 | 
						||
| 
								 | 
							
								  /** Implements path.isAbsolute */
							 | 
						||
| 
								 | 
							
								  isAbsolute: typeof pa.isAbsolute;
							 | 
						||
| 
								 | 
							
								  /** Implements path.join */
							 | 
						||
| 
								 | 
							
								  join: typeof pa.join;
							 | 
						||
| 
								 | 
							
								  /** Implements path.basename */
							 | 
						||
| 
								 | 
							
								  basename: typeof pa.basename;
							 | 
						||
| 
								 | 
							
								  /** Implements path.dirname */
							 | 
						||
| 
								 | 
							
								  dirname: typeof pa.dirname;
							 | 
						||
| 
								 | 
							
								  /** Implements (sep) => sep === path.sep */
							 | 
						||
| 
								 | 
							
								  isSeparator(char: string): boolean;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 *  Require options for a VM
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								export interface VMRequire {
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								   * Array of allowed built-in modules, accepts ["*"] for all. Using "*" increases the attack surface and potential
							 | 
						||
| 
								 | 
							
								   * new modules allow to escape the sandbox. (default: none)
							 | 
						||
| 
								 | 
							
								   */
							 | 
						||
| 
								 | 
							
								  builtin?: string[];
							 | 
						||
| 
								 | 
							
								  /*
							 | 
						||
| 
								 | 
							
								   * `host` (default) to require modules in host and proxy them to sandbox. `sandbox` to load, compile and
							 | 
						||
| 
								 | 
							
								   * require modules in sandbox. Built-in modules except `events` always required in host and proxied to sandbox
							 | 
						||
| 
								 | 
							
								   */
							 | 
						||
| 
								 | 
							
								  context?: "host" | "sandbox";
							 | 
						||
| 
								 | 
							
								  /** `true`, an array of allowed external modules or an object with external options (default: `false`) */
							 | 
						||
| 
								 | 
							
								  external?: boolean | string[] | { modules: string[], transitive: boolean };
							 | 
						||
| 
								 | 
							
								  /** Array of modules to be loaded into NodeVM on start. */
							 | 
						||
| 
								 | 
							
								  import?: string[];
							 | 
						||
| 
								 | 
							
								  /** Restricted path(s) where local modules can be required (default: every path). */
							 | 
						||
| 
								 | 
							
								  root?: string | string[];
							 | 
						||
| 
								 | 
							
								  /** Collection of mock modules (both external or built-in). */
							 | 
						||
| 
								 | 
							
								  mock?: any;
							 | 
						||
| 
								 | 
							
								  /* An additional lookup function in case a module wasn't found in one of the traditional node lookup paths. */
							 | 
						||
| 
								 | 
							
								  resolve?: (moduleName: string, parentDirname: string) => string | undefined;
							 | 
						||
| 
								 | 
							
								  /** Custom require to require host and built-in modules. */
							 | 
						||
| 
								 | 
							
								  customRequire?: (id: string) => any;
							 | 
						||
| 
								 | 
							
								  /** Load modules in strict mode. (default: true) */
							 | 
						||
| 
								 | 
							
								  strict?: boolean;
							 | 
						||
| 
								 | 
							
								  /** FileSystem to load files from */
							 | 
						||
| 
								 | 
							
								  fs?: VMFileSystemInterface;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * A custom compiler function for all of the JS that comes
							 | 
						||
| 
								 | 
							
								 * into the VM
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								export type CompilerFunction = (code: string, filename: string) => string;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 *  Options for creating a VM
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								export interface VMOptions {
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								   * `javascript` (default) or `coffeescript` or custom compiler function (which receives the code, and it's file path).
							 | 
						||
| 
								 | 
							
								   *  The library expects you to have coffee-script pre-installed if the compiler is set to `coffeescript`.
							 | 
						||
| 
								 | 
							
								   */
							 | 
						||
| 
								 | 
							
								  compiler?: "javascript" | "coffeescript" | CompilerFunction;
							 | 
						||
| 
								 | 
							
								  /** VM's global object. */
							 | 
						||
| 
								 | 
							
								  sandbox?: any;
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								   * Script timeout in milliseconds.  Timeout is only effective on code you run through `run`.
							 | 
						||
| 
								 | 
							
								   * Timeout is NOT effective on any method returned by VM.
							 | 
						||
| 
								 | 
							
								   */
							 | 
						||
| 
								 | 
							
								  timeout?: number;
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								   * If set to `false` any calls to eval or function constructors (`Function`, `GeneratorFunction`, etc.) will throw an
							 | 
						||
| 
								 | 
							
								   * `EvalError` (default: `true`).
							 | 
						||
| 
								 | 
							
								   */
							 | 
						||
| 
								 | 
							
								  eval?: boolean;
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								   * If set to `false` any attempt to compile a WebAssembly module will throw a `WebAssembly.CompileError` (default: `true`).
							 | 
						||
| 
								 | 
							
								   */
							 | 
						||
| 
								 | 
							
								  wasm?: boolean;
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								   * If set to `true` any attempt to run code using async will throw a `VMError` (default: `false`).
							 | 
						||
| 
								 | 
							
								   * @deprecated Use `allowAsync` instead.
							 | 
						||
| 
								 | 
							
								   */
							 | 
						||
| 
								 | 
							
								  fixAsync?: boolean;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								   * If set to `false` any attempt to run code using async will throw a `VMError` (default: `true`).
							 | 
						||
| 
								 | 
							
								   */
							 | 
						||
| 
								 | 
							
								  allowAsync?: boolean;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 *  Options for creating a NodeVM
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								export interface NodeVMOptions extends VMOptions {
							 | 
						||
| 
								 | 
							
								  /** `inherit` to enable console, `redirect` to redirect to events, `off` to disable console (default: `inherit`). */
							 | 
						||
| 
								 | 
							
								  console?: "inherit" | "redirect" | "off";
							 | 
						||
| 
								 | 
							
								  /** `true` or an object to enable `require` options (default: `false`). */
							 | 
						||
| 
								 | 
							
								  require?: boolean | VMRequire;
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								   * **WARNING**: This should be disabled. It allows to create a NodeVM form within the sandbox which could return any host module.
							 | 
						||
| 
								 | 
							
								   * `true` to enable VMs nesting (default: `false`).
							 | 
						||
| 
								 | 
							
								   */
							 | 
						||
| 
								 | 
							
								  nesting?: boolean;
							 | 
						||
| 
								 | 
							
								  /** `commonjs` (default) to wrap script into CommonJS wrapper, `none` to retrieve value returned by the script. */
							 | 
						||
| 
								 | 
							
								  wrapper?: "commonjs" | "none";
							 | 
						||
| 
								 | 
							
								  /** File extensions that the internal module resolver should accept. */
							 | 
						||
| 
								 | 
							
								  sourceExtensions?: string[];
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								   * Array of arguments passed to `process.argv`.
							 | 
						||
| 
								 | 
							
								   * This object will not be copied and the script can change this object.
							 | 
						||
| 
								 | 
							
								   */
							 | 
						||
| 
								 | 
							
								  argv?: string[];
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								   * Environment map passed to `process.env`.
							 | 
						||
| 
								 | 
							
								   * This object will not be copied and the script can change this object.
							 | 
						||
| 
								 | 
							
								   */
							 | 
						||
| 
								 | 
							
								  env?: any;
							 | 
						||
| 
								 | 
							
								  /** Run modules in strict mode. Required modules are always strict. */
							 | 
						||
| 
								 | 
							
								  strict?: boolean;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * VM is a simple sandbox, without `require` feature, to synchronously run an untrusted code.
							 | 
						||
| 
								 | 
							
								 * Only JavaScript built-in objects + Buffer are available. Scheduling functions
							 | 
						||
| 
								 | 
							
								 * (`setInterval`, `setTimeout` and `setImmediate`) are not available by default.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								export class VM {
							 | 
						||
| 
								 | 
							
								  constructor(options?: VMOptions);
							 | 
						||
| 
								 | 
							
								  /** Direct access to the global sandbox object */
							 | 
						||
| 
								 | 
							
								  readonly sandbox: any;
							 | 
						||
| 
								 | 
							
								  /** Timeout to use for the run methods */
							 | 
						||
| 
								 | 
							
								  timeout?: number;
							 | 
						||
| 
								 | 
							
								  /** Runs the code */
							 | 
						||
| 
								 | 
							
								  run(script: string | VMScript, options?: string | { filename?: string }): any;
							 | 
						||
| 
								 | 
							
								  /** Runs the code in the specific file */
							 | 
						||
| 
								 | 
							
								  runFile(filename: string): any;
							 | 
						||
| 
								 | 
							
								  /** Loads all the values into the global object with the same names */
							 | 
						||
| 
								 | 
							
								  setGlobals(values: any): this;
							 | 
						||
| 
								 | 
							
								  /** Make a object visible as a global with a specific name */
							 | 
						||
| 
								 | 
							
								  setGlobal(name: string, value: any): this;
							 | 
						||
| 
								 | 
							
								  /** Get the global object with the specific name */
							 | 
						||
| 
								 | 
							
								  getGlobal(name: string): any;
							 | 
						||
| 
								 | 
							
								  /** Freezes the object inside VM making it read-only. Not available for primitive values. */
							 | 
						||
| 
								 | 
							
								  freeze(object: any, name?: string): any;
							 | 
						||
| 
								 | 
							
								  /** Freezes the object inside VM making it read-only. Not available for primitive values. */
							 | 
						||
| 
								 | 
							
								  readonly(object: any): any;
							 | 
						||
| 
								 | 
							
								  /** Protects the object inside VM making impossible to set functions as it's properties. Not available for primitive values */
							 | 
						||
| 
								 | 
							
								  protect(object: any, name?: string): any;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * A VM with behavior more similar to running inside Node.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								export class NodeVM extends EventEmitter implements VM {
							 | 
						||
| 
								 | 
							
								  constructor(options?: NodeVMOptions);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /** Require a module in VM and return it's exports. */
							 | 
						||
| 
								 | 
							
								  require(module: string): any;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								   * Create NodeVM and run code inside it.
							 | 
						||
| 
								 | 
							
								   *
							 | 
						||
| 
								 | 
							
								   * @param {string} script JavaScript code.
							 | 
						||
| 
								 | 
							
								   * @param {string} [filename] File name (used in stack traces only).
							 | 
						||
| 
								 | 
							
								   * @param {Object} [options] VM options.
							 | 
						||
| 
								 | 
							
								   */
							 | 
						||
| 
								 | 
							
								  static code(script: string, filename?: string, options?: NodeVMOptions): any;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								   * Create NodeVM and run script from file inside it.
							 | 
						||
| 
								 | 
							
								   *
							 | 
						||
| 
								 | 
							
								   * @param {string} [filename] File name (used in stack traces only).
							 | 
						||
| 
								 | 
							
								   * @param {Object} [options] VM options.
							 | 
						||
| 
								 | 
							
								   */
							 | 
						||
| 
								 | 
							
								  static file(filename: string, options?: NodeVMOptions): any;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /** Direct access to the global sandbox object */
							 | 
						||
| 
								 | 
							
								  readonly sandbox: any;
							 | 
						||
| 
								 | 
							
								  /** Only here because of implements VM. Does nothing. */
							 | 
						||
| 
								 | 
							
								  timeout?: number;
							 | 
						||
| 
								 | 
							
								  /** Runs the code */
							 | 
						||
| 
								 | 
							
								  run(js: string | VMScript, options?: string | { filename?: string, wrapper?: "commonjs" | "none", strict?: boolean }): any;
							 | 
						||
| 
								 | 
							
								  /** Runs the code in the specific file */
							 | 
						||
| 
								 | 
							
								  runFile(filename: string): any;
							 | 
						||
| 
								 | 
							
								  /** Loads all the values into the global object with the same names */
							 | 
						||
| 
								 | 
							
								  setGlobals(values: any): this;
							 | 
						||
| 
								 | 
							
								  /** Make a object visible as a global with a specific name */
							 | 
						||
| 
								 | 
							
								  setGlobal(name: string, value: any): this;
							 | 
						||
| 
								 | 
							
								  /** Get the global object with the specific name */
							 | 
						||
| 
								 | 
							
								  getGlobal(name: string): any;
							 | 
						||
| 
								 | 
							
								  /** Freezes the object inside VM making it read-only. Not available for primitive values. */
							 | 
						||
| 
								 | 
							
								  freeze(object: any, name?: string): any;
							 | 
						||
| 
								 | 
							
								  /** Freezes the object inside VM making it read-only. Not available for primitive values. */
							 | 
						||
| 
								 | 
							
								  readonly(object: any): any;
							 | 
						||
| 
								 | 
							
								  /** Protects the object inside VM making impossible to set functions as it's properties. Not available for primitive values */
							 | 
						||
| 
								 | 
							
								  protect(object: any, name?: string): any;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * You can increase performance by using pre-compiled scripts.
							 | 
						||
| 
								 | 
							
								 * The pre-compiled VMScript can be run later multiple times. It is important to note that the code is not bound
							 | 
						||
| 
								 | 
							
								 * to any VM (context); rather, it is bound before each run, just for that run.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								export class VMScript {
							 | 
						||
| 
								 | 
							
								  constructor(code: string, path: string, options?: {
							 | 
						||
| 
								 | 
							
								    lineOffset?: number;
							 | 
						||
| 
								 | 
							
								    columnOffset?: number;
							 | 
						||
| 
								 | 
							
								    compiler?: "javascript" | "coffeescript" | CompilerFunction;
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  constructor(code: string, options?: {
							 | 
						||
| 
								 | 
							
								    filename?: string,
							 | 
						||
| 
								 | 
							
								    lineOffset?: number;
							 | 
						||
| 
								 | 
							
								    columnOffset?: number;
							 | 
						||
| 
								 | 
							
								    compiler?: "javascript" | "coffeescript" | CompilerFunction;
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  readonly code: string;
							 | 
						||
| 
								 | 
							
								  readonly filename: string;
							 | 
						||
| 
								 | 
							
								  readonly lineOffset: number;
							 | 
						||
| 
								 | 
							
								  readonly columnOffset: number;
							 | 
						||
| 
								 | 
							
								  readonly compiler: "javascript" | "coffeescript" | CompilerFunction;
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								   * Wraps the code
							 | 
						||
| 
								 | 
							
								   * @deprecated
							 | 
						||
| 
								 | 
							
								   */
							 | 
						||
| 
								 | 
							
								  wrap(prefix: string, postfix: string): this;
							 | 
						||
| 
								 | 
							
								  /** Compiles the code. If called multiple times, the code is only compiled once. */
							 | 
						||
| 
								 | 
							
								  compile(): this;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/** Custom Error class */
							 | 
						||
| 
								 | 
							
								export class VMError extends Error { }
							 |