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;

`