@@ -3,13 +3,16 @@ import fs from 'fs';
3
3
import url from 'url' ;
4
4
import test from 'ava' ;
5
5
import vm from 'vm' ;
6
+ import Buffer from 'buffer' ;
7
+ import { writeZip } from '@endo/zip' ;
6
8
import {
7
9
makeBundle ,
8
10
makeSecureBundle ,
9
11
makeSecureBundleFromArchive ,
10
12
makeArchive ,
11
13
parseArchive ,
12
14
} from '../index.js' ;
15
+ import { addSourcesToArchive } from '../src/archive.js' ;
13
16
import { makeReadPowers } from '../node-powers.js' ;
14
17
import { getVmEvalKitUnderLockdown } from './run-in-context.js' ;
15
18
@@ -18,6 +21,7 @@ const fixture = new URL(
18
21
import . meta. url ,
19
22
) . toString ( ) ;
20
23
24
+ const textEncoder = new TextEncoder ( ) ;
21
25
const { read } = makeReadPowers ( { fs, url } ) ;
22
26
23
27
const expectedLog = [
@@ -183,3 +187,66 @@ test('secure bundler safely sandboxes modules', async t => {
183
187
t . falsy ( vmGlobalThis . pollution ) ;
184
188
}
185
189
} ) ;
190
+
191
+ test . failing ( 'ensure bundling from archive validates sources' , async t => {
192
+ const compartmentMapDescriptor = {
193
+ entry : {
194
+ module : 'main.js' ,
195
+ compartment : 'xyz' ,
196
+ } ,
197
+ compartments : {
198
+ xyz : {
199
+ name : 'xyz' ,
200
+ label : 'xyz' ,
201
+ location : 'xyz' ,
202
+ modules : {
203
+ 'main.js' : {
204
+ location : 'main.js' ,
205
+ parser : 'pre-cjs-json' ,
206
+ } ,
207
+ } ,
208
+ } ,
209
+ } ,
210
+ } ;
211
+
212
+ const moduleSource = `} // invalid js` ;
213
+ const moduleBytes = textEncoder . encode (
214
+ JSON . stringify ( {
215
+ imports : [ ] ,
216
+ exports : [ ] ,
217
+ reexports : [ ] ,
218
+ source : moduleSource ,
219
+ } ) ,
220
+ ) ;
221
+
222
+ const archiveSources = {
223
+ xyz : {
224
+ 'main.js' : {
225
+ location : 'main.js' ,
226
+ bytes : moduleBytes ,
227
+ } ,
228
+ } ,
229
+ } ;
230
+
231
+ const archive = writeZip ( ) ;
232
+ const compartmentMapBytes = Buffer . from (
233
+ JSON . stringify ( compartmentMapDescriptor ) ,
234
+ 'utf8' ,
235
+ ) ;
236
+ await archive . write ( 'compartment-map.json' , compartmentMapBytes ) ;
237
+ await addSourcesToArchive ( archive , archiveSources ) ;
238
+ const archiveBytes = await archive . snapshot ( ) ;
239
+
240
+ const fakeArchiveLocation = new URL ( 'app.agar' , import . meta. url ) . toString ( ) ;
241
+ const readWithArchive = async path => {
242
+ if ( path === fakeArchiveLocation ) {
243
+ return archiveBytes ;
244
+ }
245
+ throw new Error ( `unexpected read: ${ path } ` ) ;
246
+ } ;
247
+
248
+ // should validate that the module source is valid
249
+ await t . throwsAsync ( async ( ) => {
250
+ await makeSecureBundleFromArchive ( readWithArchive , fakeArchiveLocation ) ;
251
+ } ) ;
252
+ } ) ;
0 commit comments