@novolobos/nodevm 3.10.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/builtin.js ADDED
@@ -0,0 +1,147 @@
1
+
2
+ const fs = require('fs');
3
+ const nmod = require('module');
4
+ const {EventEmitter} = require('events');
5
+ const util = require('util');
6
+ const {VMScript} = require('./script');
7
+ const {VM} = require('./vm');
8
+
9
+ const eventsModules = new WeakMap();
10
+
11
+ function defaultBuiltinLoaderEvents(vm) {
12
+ return eventsModules.get(vm);
13
+ }
14
+
15
+ let cacheBufferScript;
16
+
17
+ function defaultBuiltinLoaderBuffer(vm) {
18
+ if (!cacheBufferScript) {
19
+ cacheBufferScript = new VMScript('return buffer=>({Buffer: buffer});', {__proto__: null, filename: 'buffer.js'});
20
+ }
21
+ const makeBuffer = vm.run(cacheBufferScript, {__proto__: null, strict: true, wrapper: 'none'});
22
+ return makeBuffer(Buffer);
23
+ }
24
+
25
+ let cacheUtilScript;
26
+
27
+ function defaultBuiltinLoaderUtil(vm) {
28
+ if (!cacheUtilScript) {
29
+ cacheUtilScript = new VMScript(`return function inherits(ctor, superCtor) {
30
+ ctor.super_ = superCtor;
31
+ Object.setPrototypeOf(ctor.prototype, superCtor.prototype);
32
+ }`, {__proto__: null, filename: 'util.js'});
33
+ }
34
+ const inherits = vm.run(cacheUtilScript, {__proto__: null, strict: true, wrapper: 'none'});
35
+ const copy = Object.assign({}, util);
36
+ copy.inherits = inherits;
37
+ return vm.readonly(copy);
38
+ }
39
+
40
+ const BUILTIN_MODULES = (nmod.builtinModules || Object.getOwnPropertyNames(process.binding('natives'))).filter(s=>!s.startsWith('internal/'));
41
+
42
+ let EventEmitterReferencingAsyncResourceClass = null;
43
+ if (EventEmitter.EventEmitterAsyncResource) {
44
+ // eslint-disable-next-line global-require
45
+ const {AsyncResource} = require('async_hooks');
46
+ const kEventEmitter = Symbol('kEventEmitter');
47
+ class EventEmitterReferencingAsyncResource extends AsyncResource {
48
+ constructor(ee, type, options) {
49
+ super(type, options);
50
+ this[kEventEmitter] = ee;
51
+ }
52
+ get eventEmitter() {
53
+ return this[kEventEmitter];
54
+ }
55
+ }
56
+ EventEmitterReferencingAsyncResourceClass = EventEmitterReferencingAsyncResource;
57
+ }
58
+
59
+ let cacheEventsScript;
60
+
61
+ const SPECIAL_MODULES = {
62
+ events: {
63
+ init(vm) {
64
+ if (!cacheEventsScript) {
65
+ const eventsSource = fs.readFileSync(`${__dirname}/events.js`, 'utf8');
66
+ cacheEventsScript = new VMScript(`(function (fromhost) { const module = {}; module.exports={};{ ${eventsSource}
67
+ } return module.exports;})`, {filename: 'events.js'});
68
+ }
69
+ const closure = VM.prototype.run.call(vm, cacheEventsScript);
70
+ const eventsInstance = closure(vm.readonly({
71
+ kErrorMonitor: EventEmitter.errorMonitor,
72
+ once: EventEmitter.once,
73
+ on: EventEmitter.on,
74
+ getEventListeners: EventEmitter.getEventListeners,
75
+ EventEmitterReferencingAsyncResource: EventEmitterReferencingAsyncResourceClass
76
+ }));
77
+ eventsModules.set(vm, eventsInstance);
78
+ vm._addProtoMapping(EventEmitter.prototype, eventsInstance.EventEmitter.prototype);
79
+ },
80
+ load: defaultBuiltinLoaderEvents
81
+ },
82
+ buffer: defaultBuiltinLoaderBuffer,
83
+ util: defaultBuiltinLoaderUtil
84
+ };
85
+
86
+ function addDefaultBuiltin(builtins, key, hostRequire) {
87
+ if (builtins.has(key)) return;
88
+ const special = SPECIAL_MODULES[key];
89
+ builtins.set(key, special ? special : vm => vm.readonly(hostRequire(key)));
90
+ }
91
+
92
+
93
+ function makeBuiltinsFromLegacyOptions(builtins, hostRequire, mocks, overrides) {
94
+ const res = new Map();
95
+ if (mocks) {
96
+ const keys = Object.getOwnPropertyNames(mocks);
97
+ for (let i = 0; i < keys.length; i++) {
98
+ const key = keys[i];
99
+ res.set(key, (tvm) => tvm.readonly(mocks[key]));
100
+ }
101
+ }
102
+ if (overrides) {
103
+ const keys = Object.getOwnPropertyNames(overrides);
104
+ for (let i = 0; i < keys.length; i++) {
105
+ const key = keys[i];
106
+ res.set(key, overrides[key]);
107
+ }
108
+ }
109
+ if (Array.isArray(builtins)) {
110
+ const def = builtins.indexOf('*') >= 0;
111
+ if (def) {
112
+ for (let i = 0; i < BUILTIN_MODULES.length; i++) {
113
+ const name = BUILTIN_MODULES[i];
114
+ if (builtins.indexOf(`-${name}`) === -1) {
115
+ addDefaultBuiltin(res, name, hostRequire);
116
+ }
117
+ }
118
+ } else {
119
+ for (let i = 0; i < BUILTIN_MODULES.length; i++) {
120
+ const name = BUILTIN_MODULES[i];
121
+ if (builtins.indexOf(name) !== -1) {
122
+ addDefaultBuiltin(res, name, hostRequire);
123
+ }
124
+ }
125
+ }
126
+ } else if (builtins) {
127
+ for (let i = 0; i < BUILTIN_MODULES.length; i++) {
128
+ const name = BUILTIN_MODULES[i];
129
+ if (builtins[name]) {
130
+ addDefaultBuiltin(res, name, hostRequire);
131
+ }
132
+ }
133
+ }
134
+ return res;
135
+ }
136
+
137
+ function makeBuiltins(builtins, hostRequire) {
138
+ const res = new Map();
139
+ for (let i = 0; i < builtins.length; i++) {
140
+ const name = builtins[i];
141
+ addDefaultBuiltin(res, name, hostRequire);
142
+ }
143
+ return res;
144
+ }
145
+
146
+ exports.makeBuiltinsFromLegacyOptions = makeBuiltinsFromLegacyOptions;
147
+ exports.makeBuiltins = makeBuiltins;
package/lib/cli.js ADDED
@@ -0,0 +1,35 @@
1
+ 'use strict';
2
+
3
+ const pa = require('path');
4
+
5
+ const {NodeVM, VMError} = require('../');
6
+
7
+ if (process.argv[2]) {
8
+ const path = pa.resolve(process.argv[2]);
9
+
10
+ console.log(`\x1B[90m[vm] creating VM for ${path}\x1B[39m`);
11
+ const started = Date.now();
12
+
13
+ try {
14
+ NodeVM.file(path, {
15
+ verbose: true,
16
+ require: {
17
+ external: true
18
+ }
19
+ });
20
+
21
+ console.log(`\x1B[90m[vm] VM completed in ${Date.now() - started}ms\x1B[39m`);
22
+ } catch (ex) {
23
+ if (ex instanceof VMError) {
24
+ console.error(`\x1B[31m[vm:error] ${ex.message}\x1B[39m`);
25
+ } else {
26
+ const {stack} = ex;
27
+
28
+ if (stack) {
29
+ console.error(`\x1B[31m[vm:error] ${stack}\x1B[39m`);
30
+ } else {
31
+ console.error(`\x1B[31m[vm:error] ${ex}\x1B[39m`);
32
+ }
33
+ }
34
+ }
35
+ }
@@ -0,0 +1,117 @@
1
+ 'use strict';
2
+
3
+ const {
4
+ VMError
5
+ } = require('./bridge');
6
+
7
+ /**
8
+ * Returns the cached coffee script compiler or loads it
9
+ * if it is not found in the cache.
10
+ *
11
+ * @private
12
+ * @param {Object} [options] - Optional compiler options.
13
+ * @return {compileCallback} The coffee script compiler.
14
+ * @throws {VMError} If the coffee-script module can't be found.
15
+ */
16
+ function getCoffeeScriptCompiler(options) {
17
+ try {
18
+ // The warning generated by webpack can be disabled by setting:
19
+ // ignoreWarnings[].message = /Can't resolve 'coffee-script'/
20
+ /* eslint-disable-next-line global-require */
21
+ const coffeeScript = require('coffee-script');
22
+ return (code, filename) => {
23
+ return coffeeScript.compile(code, Object.assign({header: false, bare: true}, options));
24
+ };
25
+ } catch (e) {
26
+ throw new VMError('Coffee-Script compiler is not installed.');
27
+ }
28
+ }
29
+
30
+ /**
31
+ * Returns the cached TypeScript compiler or loads it
32
+ * if it is not found in the cache.
33
+ *
34
+ * @private
35
+ * @param {Object} [options] - Optional compiler options.
36
+ * @return {compileCallback} The TypeScript compiler.
37
+ * @throws {VMError} If the TypeScript module can't be found.
38
+ */
39
+ function getTypeScriptCompiler(options) {
40
+ try {
41
+ // The warning generated by webpack can be disabled by setting:
42
+ // ignoreWarnings[].message = /Can't resolve 'typescript'/
43
+ /* eslint-disable-next-line global-require */
44
+ const typescript = require('typescript');
45
+ return (code, filename) => {
46
+ return typescript.transpileModule(code, {
47
+ fileName: filename,
48
+ compilerOptions: Object.assign({
49
+ module: typescript.ModuleKind.CommonJS,
50
+ }, options)
51
+ }).outputText;
52
+ };
53
+ } catch (e) {
54
+ throw new VMError('TypeScript compiler is not installed.');
55
+ }
56
+ }
57
+
58
+ /**
59
+ * Remove the shebang from source code.
60
+ *
61
+ * @private
62
+ * @param {string} code - Code from which to remove the shebang.
63
+ * @return {string} code without the shebang.
64
+ */
65
+ function removeShebang(code) {
66
+ if (!code.startsWith('#!')) return code;
67
+ return '//' + code.substring(2);
68
+ }
69
+
70
+
71
+ /**
72
+ * The JavaScript compiler, just a identity function.
73
+ *
74
+ * @private
75
+ * @type {compileCallback}
76
+ * @param {string} code - The JavaScript code.
77
+ * @param {string} filename - Filename of this script.
78
+ * @return {string} The code.
79
+ */
80
+ function jsCompiler(code, filename) {
81
+ return removeShebang(code);
82
+ }
83
+
84
+ /**
85
+ * Look up the compiler for a specific name.
86
+ *
87
+ * @private
88
+ * @param {(string|compileCallback)} compiler - A compile callback or the name of the compiler.
89
+ * @param {Object} [options] - Optional compiler options.
90
+ * @return {compileCallback} The resolved compiler.
91
+ * @throws {VMError} If the compiler is unknown or the coffee script module was needed and couldn't be found.
92
+ */
93
+ function lookupCompiler(compiler, options) {
94
+ if ('function' === typeof compiler) return compiler;
95
+ switch (compiler) {
96
+ case 'coffeescript':
97
+ case 'coffee-script':
98
+ case 'cs':
99
+ case 'text/coffeescript':
100
+ return getCoffeeScriptCompiler(options);
101
+ case 'javascript':
102
+ case 'java-script':
103
+ case 'js':
104
+ case 'text/javascript':
105
+ return jsCompiler;
106
+ case 'typescript':
107
+ case 'type-script':
108
+ case 'ts':
109
+ case 'text/typescript':
110
+ return getTypeScriptCompiler(options);
111
+ default:
112
+ throw new VMError(`Unsupported compiler '${compiler}'.`);
113
+ }
114
+ }
115
+
116
+ exports.removeShebang = removeShebang;
117
+ exports.lookupCompiler = lookupCompiler;