Merge branch 'master' of https://github.com/patriksimek/vm2 · patriksimek/vm2@f5a129a (original) (raw)
``
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;
`