@@ -11,6 +11,12 @@ const {
11
11
StringPrototypeReplace,
12
12
} = primordials ;
13
13
14
+ let _TYPES = null ;
15
+ function lazyTypes ( ) {
16
+ if ( _TYPES !== null ) return _TYPES ;
17
+ return _TYPES = require ( 'internal/util/types' ) ;
18
+ }
19
+
14
20
const {
15
21
stripBOM,
16
22
loadNativeModule
@@ -26,7 +32,10 @@ const createDynamicModule = require(
26
32
const { fileURLToPath, URL } = require ( 'url' ) ;
27
33
const { debuglog } = require ( 'internal/util/debuglog' ) ;
28
34
const { emitExperimentalWarning } = require ( 'internal/util' ) ;
29
- const { ERR_UNKNOWN_BUILTIN_MODULE } = require ( 'internal/errors' ) . codes ;
35
+ const {
36
+ ERR_UNKNOWN_BUILTIN_MODULE ,
37
+ ERR_INVALID_RETURN_PROPERTY_VALUE
38
+ } = require ( 'internal/errors' ) . codes ;
30
39
const { maybeCacheSourceMap } = require ( 'internal/source_map/source_map_cache' ) ;
31
40
const moduleWrap = internalBinding ( 'module_wrap' ) ;
32
41
const { ModuleWrap } = moduleWrap ;
@@ -39,6 +48,30 @@ const debug = debuglog('esm');
39
48
const translators = new SafeMap ( ) ;
40
49
exports . translators = translators ;
41
50
51
+ let DECODER = null ;
52
+ function assertBufferSource ( body , allowString , hookName ) {
53
+ if ( allowString && typeof body === 'string' ) {
54
+ return ;
55
+ }
56
+ const { isArrayBufferView, isAnyArrayBuffer } = lazyTypes ( ) ;
57
+ if ( isArrayBufferView ( body ) || isAnyArrayBuffer ( body ) ) {
58
+ return ;
59
+ }
60
+ throw new ERR_INVALID_RETURN_PROPERTY_VALUE (
61
+ `${ allowString ? 'string, ' : '' } array buffer, or typed array` ,
62
+ hookName ,
63
+ 'source' ,
64
+ body
65
+ ) ;
66
+ }
67
+
68
+ function stringify ( body ) {
69
+ if ( typeof body === 'string' ) return body ;
70
+ assertBufferSource ( body , false , 'transformSource' ) ;
71
+ DECODER = DECODER === null ? new TextDecoder ( ) : DECODER ;
72
+ return DECODER . decode ( body ) ;
73
+ }
74
+
42
75
function errPath ( url ) {
43
76
const parsed = new URL ( url ) ;
44
77
if ( parsed . protocol === 'file:' ) {
@@ -80,9 +113,10 @@ function initializeImportMeta(meta, { url }) {
80
113
translators . set ( 'module' , async function moduleStrategy ( url ) {
81
114
let { source } = await this . _getSource (
82
115
url , { format : 'module' } , defaultGetSource ) ;
83
- source = ` ${ source } ` ;
116
+ assertBufferSource ( source , true , 'getSource' ) ;
84
117
( { source } = await this . _transformSource (
85
118
source , { url, format : 'module' } , defaultTransformSource ) ) ;
119
+ source = stringify ( source ) ;
86
120
maybeCacheSourceMap ( url , source ) ;
87
121
debug ( `Translating StandardModule ${ url } ` ) ;
88
122
const module = new ModuleWrap ( url , undefined , source , 0 , 0 ) ;
@@ -157,9 +191,10 @@ translators.set('json', async function jsonStrategy(url) {
157
191
}
158
192
let { source } = await this . _getSource (
159
193
url , { format : 'json' } , defaultGetSource ) ;
160
- source = ` ${ source } ` ;
194
+ assertBufferSource ( source , true , 'getSource' ) ;
161
195
( { source } = await this . _transformSource (
162
196
source , { url, format : 'json' } , defaultTransformSource ) ) ;
197
+ source = stringify ( source ) ;
163
198
if ( pathname ) {
164
199
// A require call could have been called on the same file during loading and
165
200
// that resolves synchronously. To make sure we always return the identical
@@ -200,8 +235,10 @@ translators.set('wasm', async function(url) {
200
235
emitExperimentalWarning ( 'Importing Web Assembly modules' ) ;
201
236
let { source } = await this . _getSource (
202
237
url , { format : 'wasm' } , defaultGetSource ) ;
238
+ assertBufferSource ( source , false , 'getSource' ) ;
203
239
( { source } = await this . _transformSource (
204
240
source , { url, format : 'wasm' } , defaultTransformSource ) ) ;
241
+ assertBufferSource ( source , false , 'transformSource' ) ;
205
242
debug ( `Translating WASMModule ${ url } ` ) ;
206
243
let compiled ;
207
244
try {
0 commit comments