API/api.medcify.app/node_modules/vm2/lib/script.js
2022-09-26 11:41:44 +05:30

389 lines
8.9 KiB
JavaScript

'use strict';
const {Script} = require('vm');
const {
lookupCompiler,
removeShebang
} = require('./compiler');
const {
transformer
} = require('./transformer');
const objectDefineProperties = Object.defineProperties;
const MODULE_PREFIX = '(function (exports, require, module, __filename, __dirname) { ';
const STRICT_MODULE_PREFIX = MODULE_PREFIX + '"use strict"; ';
const MODULE_SUFFIX = '\n});';
/**
* Class Script
*
* @public
*/
class VMScript {
/**
* The script code with wrapping. If set will invalidate the cache.<br>
* Writable only for backwards compatibility.
*
* @public
* @readonly
* @member {string} code
* @memberOf VMScript#
*/
/**
* The filename used for this script.
*
* @public
* @readonly
* @since v3.9.0
* @member {string} filename
* @memberOf VMScript#
*/
/**
* The line offset use for stack traces.
*
* @public
* @readonly
* @since v3.9.0
* @member {number} lineOffset
* @memberOf VMScript#
*/
/**
* The column offset use for stack traces.
*
* @public
* @readonly
* @since v3.9.0
* @member {number} columnOffset
* @memberOf VMScript#
*/
/**
* The compiler to use to get the JavaScript code.
*
* @public
* @readonly
* @since v3.9.0
* @member {(string|compileCallback)} compiler
* @memberOf VMScript#
*/
/**
* The prefix for the script.
*
* @private
* @member {string} _prefix
* @memberOf VMScript#
*/
/**
* The suffix for the script.
*
* @private
* @member {string} _suffix
* @memberOf VMScript#
*/
/**
* The compiled vm.Script for the VM or if not compiled <code>null</code>.
*
* @private
* @member {?vm.Script} _compiledVM
* @memberOf VMScript#
*/
/**
* The compiled vm.Script for the NodeVM or if not compiled <code>null</code>.
*
* @private
* @member {?vm.Script} _compiledNodeVM
* @memberOf VMScript#
*/
/**
* The compiled vm.Script for the NodeVM in strict mode or if not compiled <code>null</code>.
*
* @private
* @member {?vm.Script} _compiledNodeVMStrict
* @memberOf VMScript#
*/
/**
* The resolved compiler to use to get the JavaScript code.
*
* @private
* @readonly
* @member {compileCallback} _compiler
* @memberOf VMScript#
*/
/**
* The script to run without wrapping.
*
* @private
* @member {string} _code
* @memberOf VMScript#
*/
/**
* Whether or not the script contains async functions.
*
* @private
* @member {boolean} _hasAsync
* @memberOf VMScript#
*/
/**
* Create VMScript instance.
*
* @public
* @param {string} code - Code to run.
* @param {(string|Object)} [options] - Options map or filename.
* @param {string} [options.filename="vm.js"] - Filename that shows up in any stack traces produced from this script.
* @param {number} [options.lineOffset=0] - Passed to vm.Script options.
* @param {number} [options.columnOffset=0] - Passed to vm.Script options.
* @param {(string|compileCallback)} [options.compiler="javascript"] - The compiler to use.
* @throws {VMError} If the compiler is unknown or if coffee-script was requested but the module not found.
*/
constructor(code, options) {
const sCode = `${code}`;
let useFileName;
let useOptions;
if (arguments.length === 2) {
if (typeof options === 'object') {
useOptions = options || {__proto__: null};
useFileName = useOptions.filename;
} else {
useOptions = {__proto__: null};
useFileName = options;
}
} else if (arguments.length > 2) {
// We do it this way so that there are no more arguments in the function.
// eslint-disable-next-line prefer-rest-params
useOptions = arguments[2] || {__proto__: null};
useFileName = options || useOptions.filename;
} else {
useOptions = {__proto__: null};
}
const {
compiler = 'javascript',
lineOffset = 0,
columnOffset = 0
} = useOptions;
// Throw if the compiler is unknown.
const resolvedCompiler = lookupCompiler(compiler);
objectDefineProperties(this, {
__proto__: null,
code: {
__proto__: null,
// Put this here so that it is enumerable, and looks like a property.
get() {
return this._prefix + this._code + this._suffix;
},
set(value) {
const strNewCode = String(value);
if (strNewCode === this._code && this._prefix === '' && this._suffix === '') return;
this._code = strNewCode;
this._prefix = '';
this._suffix = '';
this._compiledVM = null;
this._compiledNodeVM = null;
this._compiledCode = null;
},
enumerable: true
},
filename: {
__proto__: null,
value: useFileName || 'vm.js',
enumerable: true
},
lineOffset: {
__proto__: null,
value: lineOffset,
enumerable: true
},
columnOffset: {
__proto__: null,
value: columnOffset,
enumerable: true
},
compiler: {
__proto__: null,
value: compiler,
enumerable: true
},
_code: {
__proto__: null,
value: sCode,
writable: true
},
_prefix: {
__proto__: null,
value: '',
writable: true
},
_suffix: {
__proto__: null,
value: '',
writable: true
},
_compiledVM: {
__proto__: null,
value: null,
writable: true
},
_compiledNodeVM: {
__proto__: null,
value: null,
writable: true
},
_compiledNodeVMStrict: {
__proto__: null,
value: null,
writable: true
},
_compiledCode: {
__proto__: null,
value: null,
writable: true
},
_hasAsync: {
__proto__: null,
value: false,
writable: true
},
_compiler: {__proto__: null, value: resolvedCompiler}
});
}
/**
* Wraps the code.<br>
* This will replace the old wrapping.<br>
* Will invalidate the code cache.
*
* @public
* @deprecated Since v3.9.0. Wrap your code before passing it into the VMScript object.
* @param {string} prefix - String that will be appended before the script code.
* @param {script} suffix - String that will be appended behind the script code.
* @return {this} This for chaining.
* @throws {TypeError} If prefix or suffix is a Symbol.
*/
wrap(prefix, suffix) {
const strPrefix = `${prefix}`;
const strSuffix = `${suffix}`;
if (this._prefix === strPrefix && this._suffix === strSuffix) return this;
this._prefix = strPrefix;
this._suffix = strSuffix;
this._compiledVM = null;
this._compiledNodeVM = null;
this._compiledNodeVMStrict = null;
return this;
}
/**
* Compile this script. <br>
* This is useful to detect syntax errors in the script.
*
* @public
* @return {this} This for chaining.
* @throws {SyntaxError} If there is a syntax error in the script.
*/
compile() {
this._compileVM();
return this;
}
/**
* Get the compiled code.
*
* @private
* @return {string} The code.
*/
getCompiledCode() {
if (!this._compiledCode) {
const comp = this._compiler(this._prefix + removeShebang(this._code) + this._suffix, this.filename);
const res = transformer(null, comp, false, false, this.filename);
this._compiledCode = res.code;
this._hasAsync = res.hasAsync;
}
return this._compiledCode;
}
/**
* Compiles this script to a vm.Script.
*
* @private
* @param {string} prefix - JavaScript code that will be used as prefix.
* @param {string} suffix - JavaScript code that will be used as suffix.
* @return {vm.Script} The compiled vm.Script.
* @throws {SyntaxError} If there is a syntax error in the script.
*/
_compile(prefix, suffix) {
return new Script(prefix + this.getCompiledCode() + suffix, {
__proto__: null,
filename: this.filename,
displayErrors: false,
lineOffset: this.lineOffset,
columnOffset: this.columnOffset
});
}
/**
* Will return the cached version of the script intended for VM or compile it.
*
* @private
* @return {vm.Script} The compiled script
* @throws {SyntaxError} If there is a syntax error in the script.
*/
_compileVM() {
let script = this._compiledVM;
if (!script) {
this._compiledVM = script = this._compile('', '');
}
return script;
}
/**
* Will return the cached version of the script intended for NodeVM or compile it.
*
* @private
* @return {vm.Script} The compiled script
* @throws {SyntaxError} If there is a syntax error in the script.
*/
_compileNodeVM() {
let script = this._compiledNodeVM;
if (!script) {
this._compiledNodeVM = script = this._compile(MODULE_PREFIX, MODULE_SUFFIX);
}
return script;
}
/**
* Will return the cached version of the script intended for NodeVM in strict mode or compile it.
*
* @private
* @return {vm.Script} The compiled script
* @throws {SyntaxError} If there is a syntax error in the script.
*/
_compileNodeVMStrict() {
let script = this._compiledNodeVMStrict;
if (!script) {
this._compiledNodeVMStrict = script = this._compile(STRICT_MODULE_PREFIX, MODULE_SUFFIX);
}
return script;
}
}
exports.MODULE_PREFIX = MODULE_PREFIX;
exports.STRICT_MODULE_PREFIX = STRICT_MODULE_PREFIX;
exports.MODULE_SUFFIX = MODULE_SUFFIX;
exports.VMScript = VMScript;