@endo/compartment-mapper 1.1.5 → 1.2.0
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/README.md +17 -28
- package/archive-lite.d.ts +2 -0
- package/archive-lite.js +7 -0
- package/archive-parsers.d.ts +2 -0
- package/archive-parsers.js +1 -0
- package/capture-lite.d.ts +2 -0
- package/capture-lite.js +1 -0
- package/import-archive-lite.d.ts +2 -0
- package/import-archive-lite.js +5 -0
- package/import-archive-parsers.d.ts +2 -0
- package/import-archive-parsers.js +1 -0
- package/import-lite.d.ts +2 -0
- package/import-lite.js +1 -0
- package/import-parsers.d.ts +2 -0
- package/import-parsers.js +1 -0
- package/node-modules.d.ts +2 -0
- package/node-modules.js +1 -0
- package/package.json +23 -14
- package/src/archive-lite.d.ts +20 -0
- package/src/archive-lite.d.ts.map +1 -0
- package/src/archive-lite.js +495 -0
- package/src/archive-parsers.d.ts +11 -0
- package/src/archive-parsers.d.ts.map +1 -0
- package/src/archive-parsers.js +26 -0
- package/src/archive.d.ts +0 -6
- package/src/archive.d.ts.map +1 -1
- package/src/archive.js +94 -420
- package/src/bundle-cjs.d.ts +6 -17
- package/src/bundle-cjs.d.ts.map +1 -1
- package/src/bundle-cjs.js +11 -3
- package/src/bundle-json.d.ts +15 -0
- package/src/bundle-json.d.ts.map +1 -0
- package/src/bundle-json.js +24 -0
- package/src/bundle-mjs.d.ts +3 -19
- package/src/bundle-mjs.d.ts.map +1 -1
- package/src/bundle-mjs.js +6 -0
- package/src/bundle.d.ts +53 -10
- package/src/bundle.d.ts.map +1 -1
- package/src/bundle.js +118 -56
- package/src/capture-lite.d.ts +7 -0
- package/src/capture-lite.d.ts.map +1 -0
- package/src/capture-lite.js +324 -0
- package/src/compartment-map.d.ts +1 -1
- package/src/compartment-map.d.ts.map +1 -1
- package/src/compartment-map.js +18 -37
- package/src/extension.d.ts.map +1 -1
- package/src/extension.js +2 -0
- package/src/import-archive-lite.d.ts +26 -0
- package/src/import-archive-lite.d.ts.map +1 -0
- package/src/import-archive-lite.js +455 -0
- package/src/import-archive-parsers.d.ts +9 -0
- package/src/import-archive-parsers.d.ts.map +1 -0
- package/src/import-archive-parsers.js +24 -0
- package/src/import-archive.d.ts +12 -9
- package/src/import-archive.d.ts.map +1 -1
- package/src/import-archive.js +74 -406
- package/src/import-hook.d.ts.map +1 -1
- package/src/import-hook.js +10 -3
- package/src/import-lite.d.ts +9 -0
- package/src/import-lite.d.ts.map +1 -0
- package/src/import-lite.js +121 -0
- package/src/import-parsers.d.ts +9 -0
- package/src/import-parsers.d.ts.map +1 -0
- package/src/import-parsers.js +24 -0
- package/src/import.d.ts +1 -4
- package/src/import.d.ts.map +1 -1
- package/src/import.js +44 -97
- package/src/infer-exports.d.ts +4 -4
- package/src/infer-exports.d.ts.map +1 -1
- package/src/infer-exports.js +29 -20
- package/src/json.d.ts.map +1 -1
- package/src/json.js +1 -0
- package/src/link.d.ts +4 -4
- package/src/link.d.ts.map +1 -1
- package/src/link.js +62 -19
- package/src/node-module-specifier.d.ts.map +1 -1
- package/src/node-module-specifier.js +5 -0
- package/src/node-modules.d.ts +13 -2
- package/src/node-modules.d.ts.map +1 -1
- package/src/node-modules.js +127 -40
- package/src/node-powers.d.ts +4 -4
- package/src/node-powers.d.ts.map +1 -1
- package/src/node-powers.js +10 -0
- package/src/parse-archive-cjs.d.ts +2 -2
- package/src/parse-archive-cjs.d.ts.map +1 -1
- package/src/parse-archive-cjs.js +4 -0
- package/src/parse-archive-mjs.d.ts +2 -2
- package/src/parse-archive-mjs.d.ts.map +1 -1
- package/src/parse-archive-mjs.js +5 -2
- package/src/parse-bytes.d.ts +2 -2
- package/src/parse-bytes.d.ts.map +1 -1
- package/src/parse-bytes.js +4 -0
- package/src/parse-cjs-shared-export-wrapper.d.ts +2 -2
- package/src/parse-cjs-shared-export-wrapper.d.ts.map +1 -1
- package/src/parse-cjs-shared-export-wrapper.js +16 -1
- package/src/parse-cjs.d.ts +2 -2
- package/src/parse-cjs.d.ts.map +1 -1
- package/src/parse-cjs.js +4 -0
- package/src/parse-json.d.ts +2 -2
- package/src/parse-json.d.ts.map +1 -1
- package/src/parse-json.js +2 -0
- package/src/parse-mjs.d.ts +2 -2
- package/src/parse-mjs.d.ts.map +1 -1
- package/src/parse-mjs.js +4 -2
- package/src/parse-pre-cjs.d.ts +2 -2
- package/src/parse-pre-cjs.d.ts.map +1 -1
- package/src/parse-pre-cjs.js +6 -0
- package/src/parse-pre-mjs.d.ts +2 -2
- package/src/parse-pre-mjs.d.ts.map +1 -1
- package/src/parse-pre-mjs.js +6 -0
- package/src/parse-text.d.ts +2 -2
- package/src/parse-text.d.ts.map +1 -1
- package/src/parse-text.js +5 -0
- package/src/policy-format.d.ts +8 -6
- package/src/policy-format.d.ts.map +1 -1
- package/src/policy-format.js +12 -3
- package/src/policy.d.ts +9 -9
- package/src/policy.d.ts.map +1 -1
- package/src/policy.js +3 -0
- package/src/powers.d.ts +1 -1
- package/src/powers.d.ts.map +1 -1
- package/src/powers.js +7 -0
- package/src/search.d.ts +4 -2
- package/src/search.d.ts.map +1 -1
- package/src/search.js +22 -16
- package/src/types.d.ts +121 -15
- package/src/types.d.ts.map +1 -1
- package/src/types.js +161 -19
- package/src/url.d.ts.map +1 -1
- package/src/url.js +5 -0
package/src/import-archive.js
CHANGED
|
@@ -1,406 +1,87 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
import
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
import { assertCompartmentMap } from './compartment-map.js';
|
|
15
|
-
import { exitModuleImportHookMaker } from './import-hook.js';
|
|
16
|
-
import { attenuateModuleHook, enforceModulePolicy } from './policy.js';
|
|
17
|
-
|
|
18
|
-
/** @import {StaticModuleType} from 'ses' */
|
|
19
|
-
/** @import {Application, CompartmentDescriptor, ComputeSourceLocationHook, ComputeSourceMapLocationHook, ExecuteFn, ExecuteOptions, ExitModuleImportHook, HashFn, ImportHookMaker, LoadArchiveOptions, ParserImplementation, ReadPowers} from './types.js' */
|
|
20
|
-
|
|
21
|
-
const DefaultCompartment = Compartment;
|
|
22
|
-
|
|
23
|
-
const { Fail, quote: q } = assert;
|
|
24
|
-
|
|
25
|
-
const textDecoder = new TextDecoder();
|
|
26
|
-
|
|
27
|
-
const { freeze } = Object;
|
|
28
|
-
|
|
29
|
-
/** @type {Record<string, ParserImplementation>} */
|
|
30
|
-
const parserForLanguage = {
|
|
31
|
-
'pre-cjs-json': parserPreCjs,
|
|
32
|
-
'pre-mjs-json': parserPreMjs,
|
|
33
|
-
json: parserJson,
|
|
34
|
-
text: parserText,
|
|
35
|
-
bytes: parserBytes,
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* @param {string} errorMessage - error to throw on execute
|
|
40
|
-
* @returns {StaticModuleType}
|
|
1
|
+
/* Provides functions for evaluating modules in an archive (a zip file
|
|
2
|
+
* with a `compartment-map.json` and a file for a module and each of its
|
|
3
|
+
* transitive dependencies.)
|
|
4
|
+
*
|
|
5
|
+
* These functions accept the URL of an entry module and find its transitive
|
|
6
|
+
* dependencies through the Node.js `node_modules` conventions.
|
|
7
|
+
*
|
|
8
|
+
* These functions use the default parsers in `import-archive-parsers.js`,
|
|
9
|
+
* which support only pre-compiled ESM and CommonJS.
|
|
10
|
+
*
|
|
11
|
+
* See `import-archive-lite.js` for functions that are not coupled to these
|
|
12
|
+
* parsers or the `node_modules` conventions without necessarily entraining a
|
|
13
|
+
* dependency on Babel.
|
|
41
14
|
*/
|
|
42
|
-
const postponeErrorToExecute = errorMessage => {
|
|
43
|
-
// Return a place-holder that'd throw an error if executed
|
|
44
|
-
// This allows cjs parser to more eagerly find calls to require
|
|
45
|
-
// - if parser identified a require call that's a local function, execute will never be called
|
|
46
|
-
// - if actual required module is missing, the error will happen anyway - at execution time
|
|
47
15
|
|
|
48
|
-
|
|
49
|
-
imports: [],
|
|
50
|
-
exports: [],
|
|
51
|
-
execute: () => {
|
|
52
|
-
throw Error(errorMessage);
|
|
53
|
-
},
|
|
54
|
-
});
|
|
16
|
+
// @ts-check
|
|
55
17
|
|
|
56
|
-
|
|
57
|
-
|
|
18
|
+
import { defaultParserForLanguage } from './import-archive-parsers.js';
|
|
19
|
+
import {
|
|
20
|
+
parseArchive as parseArchiveLite,
|
|
21
|
+
loadArchive as loadArchiveLite,
|
|
22
|
+
importArchive as importArchiveLite,
|
|
23
|
+
} from './import-archive-lite.js';
|
|
24
|
+
|
|
25
|
+
const { assign, create, freeze } = Object;
|
|
26
|
+
|
|
27
|
+
/** @import {Application} from './types.js' */
|
|
28
|
+
/** @import {ComputeSourceLocationHook} from './types.js' */
|
|
29
|
+
/** @import {ComputeSourceMapLocationHook} from './types.js' */
|
|
30
|
+
/** @import {ExecuteOptions} from './types.js' */
|
|
31
|
+
/** @import {ExitModuleImportHook} from './types.js' */
|
|
32
|
+
/** @import {HashFn} from './types.js' */
|
|
33
|
+
/** @import {LoadArchiveOptions} from './types.js' */
|
|
34
|
+
/** @import {ReadPowers} from './types.js' */
|
|
35
|
+
/** @import {ParserForLanguage} from './types.js' */
|
|
36
|
+
|
|
37
|
+
// Must give the type of Compartment a name to capture the external meaning of
|
|
38
|
+
// Compartment Otherwise @param {typeof Compartment} takes the Compartment to
|
|
39
|
+
// mean the const variable defined within the function.
|
|
40
|
+
//
|
|
41
|
+
/** @typedef {typeof Compartment} CompartmentConstructor */
|
|
58
42
|
|
|
59
43
|
/**
|
|
60
|
-
* @
|
|
61
|
-
* @
|
|
62
|
-
* @
|
|
63
|
-
* @
|
|
64
|
-
* @
|
|
65
|
-
* @
|
|
66
|
-
* @
|
|
67
|
-
* @
|
|
44
|
+
* @typedef {object} Options
|
|
45
|
+
* @property {string} [expectedSha512]
|
|
46
|
+
* @property {HashFn} [computeSha512]
|
|
47
|
+
* @property {Record<string, unknown>} [modules]
|
|
48
|
+
* @property {ExitModuleImportHook} [importHook]
|
|
49
|
+
* @property {CompartmentConstructor} [Compartment]
|
|
50
|
+
* @property {ComputeSourceLocationHook} [computeSourceLocation]
|
|
51
|
+
* @property {ComputeSourceMapLocationHook} [computeSourceMapLocation]
|
|
52
|
+
* @property {ParserForLanguage} [parserForLanguage]
|
|
68
53
|
*/
|
|
69
|
-
const makeArchiveImportHookMaker = (
|
|
70
|
-
get,
|
|
71
|
-
compartments,
|
|
72
|
-
archiveLocation,
|
|
73
|
-
computeSha512 = undefined,
|
|
74
|
-
computeSourceLocation = undefined,
|
|
75
|
-
exitModuleImportHook = undefined,
|
|
76
|
-
computeSourceMapLocation = undefined,
|
|
77
|
-
) => {
|
|
78
|
-
// per-assembly:
|
|
79
|
-
/** @type {ImportHookMaker} */
|
|
80
|
-
const makeImportHook = ({
|
|
81
|
-
packageLocation,
|
|
82
|
-
packageName,
|
|
83
|
-
attenuators,
|
|
84
|
-
// note `compartments` are not passed to makeImportHook because
|
|
85
|
-
// the reference was passed to makeArchiveImportHookMaker.
|
|
86
|
-
}) => {
|
|
87
|
-
// per-compartment:
|
|
88
|
-
const compartmentDescriptor = compartments[packageLocation];
|
|
89
|
-
const { modules } = compartmentDescriptor;
|
|
90
|
-
/** @type {import('ses').ImportHook} */
|
|
91
|
-
const importHook = async moduleSpecifier => {
|
|
92
|
-
// per-module:
|
|
93
|
-
const module = modules[moduleSpecifier];
|
|
94
|
-
if (module === undefined) {
|
|
95
|
-
if (exitModuleImportHook) {
|
|
96
|
-
// At this point in archive importing, if a module is not found and
|
|
97
|
-
// exitModuleImportHook exists, the only possibility is that the
|
|
98
|
-
// module is a "builtin" module and the policy needs to be enforced.
|
|
99
|
-
enforceModulePolicy(moduleSpecifier, compartmentDescriptor, {
|
|
100
|
-
exit: true,
|
|
101
|
-
errorHint: `Blocked in loading. ${q(
|
|
102
|
-
moduleSpecifier,
|
|
103
|
-
)} was not in the archive and an attempt was made to load it as a builtin`,
|
|
104
|
-
});
|
|
105
|
-
const record = await exitModuleImportHook(moduleSpecifier);
|
|
106
|
-
if (record) {
|
|
107
|
-
// note it's not being marked as exit in sources
|
|
108
|
-
// it could get marked and the second pass, when the archive is being executed, would have the data
|
|
109
|
-
// to enforce which exits can be dynamically imported
|
|
110
|
-
return {
|
|
111
|
-
record: await attenuateModuleHook(
|
|
112
|
-
moduleSpecifier,
|
|
113
|
-
record,
|
|
114
|
-
compartmentDescriptor.policy,
|
|
115
|
-
attenuators,
|
|
116
|
-
),
|
|
117
|
-
specifier: moduleSpecifier,
|
|
118
|
-
};
|
|
119
|
-
} else {
|
|
120
|
-
// if exitModuleImportHook is allowed, the mechanism to defer
|
|
121
|
-
// errors in archive creation is never used. We don't want to
|
|
122
|
-
// throw until the module execution is attempted. This is because
|
|
123
|
-
// the cjs parser eagerly looks for require calls, and if it finds
|
|
124
|
-
// one, it will try to import the module even if the require is
|
|
125
|
-
// never reached.
|
|
126
|
-
return postponeErrorToExecute(
|
|
127
|
-
`Cannot find external module ${q(moduleSpecifier)} in package ${q(
|
|
128
|
-
packageLocation,
|
|
129
|
-
)} in archive ${q(archiveLocation)}`,
|
|
130
|
-
);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
throw Error(
|
|
134
|
-
`Cannot find module ${q(moduleSpecifier)} in package ${q(
|
|
135
|
-
packageLocation,
|
|
136
|
-
)} in archive ${q(archiveLocation)}`,
|
|
137
|
-
);
|
|
138
|
-
}
|
|
139
|
-
if (module.deferredError !== undefined) {
|
|
140
|
-
return postponeErrorToExecute(module.deferredError);
|
|
141
|
-
}
|
|
142
|
-
if (module.parser === undefined) {
|
|
143
|
-
throw Error(
|
|
144
|
-
`Cannot parse module ${q(moduleSpecifier)} in package ${q(
|
|
145
|
-
packageLocation,
|
|
146
|
-
)} in archive ${q(archiveLocation)}`,
|
|
147
|
-
);
|
|
148
|
-
}
|
|
149
|
-
if (parserForLanguage[module.parser] === undefined) {
|
|
150
|
-
throw Error(
|
|
151
|
-
`Cannot parse ${q(module.parser)} module ${q(
|
|
152
|
-
moduleSpecifier,
|
|
153
|
-
)} in package ${q(packageLocation)} in archive ${q(archiveLocation)}`,
|
|
154
|
-
);
|
|
155
|
-
}
|
|
156
|
-
const { parse } = parserForLanguage[module.parser];
|
|
157
|
-
const moduleLocation = `${packageLocation}/${module.location}`;
|
|
158
|
-
const moduleBytes = get(moduleLocation);
|
|
159
|
-
|
|
160
|
-
if (computeSha512 !== undefined && module.sha512 !== undefined) {
|
|
161
|
-
const sha512 = computeSha512(moduleBytes);
|
|
162
|
-
if (sha512 !== module.sha512) {
|
|
163
|
-
throw Error(
|
|
164
|
-
`Module ${q(module.location)} of package ${q(
|
|
165
|
-
packageLocation,
|
|
166
|
-
)} in archive ${q(
|
|
167
|
-
archiveLocation,
|
|
168
|
-
)} failed a SHA-512 integrity check`,
|
|
169
|
-
);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
let sourceLocation = `file:///${moduleLocation}`;
|
|
174
|
-
if (packageName !== undefined) {
|
|
175
|
-
const base = packageName.split('/').slice(-1).join('/');
|
|
176
|
-
sourceLocation = `.../${join(base, moduleSpecifier)}`;
|
|
177
|
-
}
|
|
178
|
-
if (computeSourceLocation !== undefined) {
|
|
179
|
-
sourceLocation =
|
|
180
|
-
computeSourceLocation(packageLocation, moduleSpecifier) ||
|
|
181
|
-
sourceLocation;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
let sourceMapUrl;
|
|
185
|
-
if (
|
|
186
|
-
computeSourceMapLocation !== undefined &&
|
|
187
|
-
module.sha512 !== undefined
|
|
188
|
-
) {
|
|
189
|
-
sourceMapUrl = computeSourceMapLocation({
|
|
190
|
-
compartment: packageLocation,
|
|
191
|
-
module: moduleSpecifier,
|
|
192
|
-
location: sourceLocation,
|
|
193
|
-
sha512: module.sha512,
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
// eslint-disable-next-line no-await-in-loop
|
|
198
|
-
const { record } = await parse(
|
|
199
|
-
moduleBytes,
|
|
200
|
-
moduleSpecifier,
|
|
201
|
-
sourceLocation,
|
|
202
|
-
packageLocation,
|
|
203
|
-
{
|
|
204
|
-
sourceMapUrl,
|
|
205
|
-
},
|
|
206
|
-
);
|
|
207
|
-
return { record, specifier: moduleSpecifier };
|
|
208
|
-
};
|
|
209
|
-
return importHook;
|
|
210
|
-
};
|
|
211
|
-
return makeImportHook;
|
|
212
|
-
};
|
|
213
54
|
|
|
214
55
|
/**
|
|
215
|
-
*
|
|
216
|
-
*
|
|
217
|
-
* @
|
|
218
|
-
* @returns {import('ses').ModuleExportsNamespace}
|
|
56
|
+
* Add the default parserForLanguage option.
|
|
57
|
+
* @param {Options} [options]
|
|
58
|
+
* @returns {Options}
|
|
219
59
|
*/
|
|
220
|
-
const
|
|
221
|
-
const
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
resolveHook() {
|
|
226
|
-
return '.';
|
|
227
|
-
},
|
|
228
|
-
async importHook() {
|
|
229
|
-
return {
|
|
230
|
-
imports: [],
|
|
231
|
-
execute() {},
|
|
232
|
-
exports: [],
|
|
233
|
-
};
|
|
234
|
-
},
|
|
235
|
-
},
|
|
60
|
+
const assignParserForLanguage = (options = {}) => {
|
|
61
|
+
const { parserForLanguage: parserForLanguageOption, ...rest } = options;
|
|
62
|
+
/** @type {ParserForLanguage} */
|
|
63
|
+
const parserForLanguage = freeze(
|
|
64
|
+
assign(create(null), defaultParserForLanguage, parserForLanguageOption),
|
|
236
65
|
);
|
|
237
|
-
return
|
|
66
|
+
return { ...rest, parserForLanguage };
|
|
238
67
|
};
|
|
239
68
|
|
|
240
|
-
// Have to give it a name to capture the external meaning of Compartment
|
|
241
|
-
// Otherwise @param {typeof Compartment} takes the Compartment to mean
|
|
242
|
-
// the const variable defined within the function.
|
|
243
|
-
/** @typedef {typeof Compartment} CompartmentConstructor */
|
|
244
|
-
|
|
245
69
|
/**
|
|
246
70
|
* @param {Uint8Array} archiveBytes
|
|
247
71
|
* @param {string} [archiveLocation]
|
|
248
|
-
* @param {
|
|
249
|
-
* @param {string} [options.expectedSha512]
|
|
250
|
-
* @param {HashFn} [options.computeSha512]
|
|
251
|
-
* @param {Record<string, unknown>} [options.modules]
|
|
252
|
-
* @param {ExitModuleImportHook} [options.importHook]
|
|
253
|
-
* @param {CompartmentConstructor} [options.Compartment]
|
|
254
|
-
* @param {ComputeSourceLocationHook} [options.computeSourceLocation]
|
|
255
|
-
* @param {ComputeSourceMapLocationHook} [options.computeSourceMapLocation]
|
|
72
|
+
* @param {Options} [options]
|
|
256
73
|
* @returns {Promise<Application>}
|
|
257
74
|
*/
|
|
258
75
|
export const parseArchive = async (
|
|
259
76
|
archiveBytes,
|
|
260
77
|
archiveLocation = '<unknown>',
|
|
261
78
|
options = {},
|
|
262
|
-
) =>
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
computeSourceMapLocation = undefined,
|
|
268
|
-
Compartment = DefaultCompartment,
|
|
269
|
-
modules = undefined,
|
|
270
|
-
importHook: exitModuleImportHook = undefined,
|
|
271
|
-
} = options;
|
|
272
|
-
|
|
273
|
-
const compartmentExitModuleImportHook = exitModuleImportHookMaker({
|
|
274
|
-
modules,
|
|
275
|
-
exitModuleImportHook,
|
|
276
|
-
});
|
|
277
|
-
|
|
278
|
-
const archive = new ZipReader(archiveBytes, { name: archiveLocation });
|
|
279
|
-
|
|
280
|
-
// Track all modules that get loaded, all files that are used.
|
|
281
|
-
const unseen = new Set(archive.files.keys());
|
|
282
|
-
unseen.size >= 2 ||
|
|
283
|
-
Fail`Archive failed sanity check: should contain at least a compartment map file and one module file in ${q(
|
|
284
|
-
archiveLocation,
|
|
285
|
-
)}`;
|
|
286
|
-
|
|
287
|
-
/**
|
|
288
|
-
* @param {string} path
|
|
289
|
-
*/
|
|
290
|
-
const get = path => {
|
|
291
|
-
unseen.delete(path);
|
|
292
|
-
return archive.read(path);
|
|
293
|
-
};
|
|
294
|
-
|
|
295
|
-
const compartmentMapBytes = get('compartment-map.json');
|
|
296
|
-
|
|
297
|
-
let sha512;
|
|
298
|
-
if (computeSha512 !== undefined) {
|
|
299
|
-
sha512 = computeSha512(compartmentMapBytes);
|
|
300
|
-
}
|
|
301
|
-
if (expectedSha512 !== undefined) {
|
|
302
|
-
if (sha512 === undefined) {
|
|
303
|
-
throw Error(
|
|
304
|
-
`Cannot verify expectedSha512 without also providing computeSha512, for archive ${archiveLocation}`,
|
|
305
|
-
);
|
|
306
|
-
}
|
|
307
|
-
if (sha512 !== expectedSha512) {
|
|
308
|
-
throw Error(
|
|
309
|
-
`Archive compartment map failed a SHA-512 integrity check, expected ${expectedSha512}, got ${sha512}, for archive ${archiveLocation}`,
|
|
310
|
-
);
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
const compartmentMapText = textDecoder.decode(compartmentMapBytes);
|
|
314
|
-
const compartmentMap = parseLocatedJson(
|
|
315
|
-
compartmentMapText,
|
|
316
|
-
'compartment-map.json',
|
|
79
|
+
) =>
|
|
80
|
+
parseArchiveLite(
|
|
81
|
+
archiveBytes,
|
|
82
|
+
archiveLocation,
|
|
83
|
+
assignParserForLanguage(options),
|
|
317
84
|
);
|
|
318
|
-
assertCompartmentMap(compartmentMap, archiveLocation);
|
|
319
|
-
|
|
320
|
-
const {
|
|
321
|
-
compartments,
|
|
322
|
-
entry: { module: moduleSpecifier },
|
|
323
|
-
} = compartmentMap;
|
|
324
|
-
|
|
325
|
-
// Archive integrity checks: ensure every module is pre-loaded so its hash
|
|
326
|
-
// gets checked, and ensure that every file in the archive is used, and
|
|
327
|
-
// therefore checked.
|
|
328
|
-
if (computeSha512 !== undefined) {
|
|
329
|
-
const makeImportHook = makeArchiveImportHookMaker(
|
|
330
|
-
get,
|
|
331
|
-
compartments,
|
|
332
|
-
archiveLocation,
|
|
333
|
-
computeSha512,
|
|
334
|
-
computeSourceLocation,
|
|
335
|
-
compartmentExitModuleImportHook,
|
|
336
|
-
computeSourceMapLocation,
|
|
337
|
-
);
|
|
338
|
-
// A weakness of the current Compartment design is that the `modules` map
|
|
339
|
-
// must be given a module namespace object that passes a brand check.
|
|
340
|
-
// We don't have module instances for the preload phase, so we supply fake
|
|
341
|
-
// namespaces.
|
|
342
|
-
const { compartment, pendingJobsPromise } = link(compartmentMap, {
|
|
343
|
-
makeImportHook,
|
|
344
|
-
parserForLanguage,
|
|
345
|
-
modules: Object.fromEntries(
|
|
346
|
-
Object.keys(modules || {}).map(specifier => {
|
|
347
|
-
return [specifier, makeFauxModuleExportsNamespace(Compartment)];
|
|
348
|
-
}),
|
|
349
|
-
),
|
|
350
|
-
Compartment,
|
|
351
|
-
});
|
|
352
|
-
|
|
353
|
-
await pendingJobsPromise;
|
|
354
|
-
|
|
355
|
-
await compartment.load(moduleSpecifier);
|
|
356
|
-
unseen.size === 0 ||
|
|
357
|
-
Fail`Archive contains extraneous files: ${q([...unseen])} in ${q(
|
|
358
|
-
archiveLocation,
|
|
359
|
-
)}`;
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
/** @type {ExecuteFn} */
|
|
363
|
-
const execute = async options => {
|
|
364
|
-
const {
|
|
365
|
-
globals,
|
|
366
|
-
modules,
|
|
367
|
-
transforms,
|
|
368
|
-
__shimTransforms__,
|
|
369
|
-
Compartment,
|
|
370
|
-
importHook: exitModuleImportHook,
|
|
371
|
-
} = options || {};
|
|
372
|
-
|
|
373
|
-
const compartmentExitModuleImportHook = exitModuleImportHookMaker({
|
|
374
|
-
modules,
|
|
375
|
-
exitModuleImportHook,
|
|
376
|
-
});
|
|
377
|
-
const makeImportHook = makeArchiveImportHookMaker(
|
|
378
|
-
get,
|
|
379
|
-
compartments,
|
|
380
|
-
archiveLocation,
|
|
381
|
-
computeSha512,
|
|
382
|
-
computeSourceLocation,
|
|
383
|
-
compartmentExitModuleImportHook,
|
|
384
|
-
computeSourceMapLocation,
|
|
385
|
-
);
|
|
386
|
-
const { compartment, pendingJobsPromise } = link(compartmentMap, {
|
|
387
|
-
makeImportHook,
|
|
388
|
-
parserForLanguage,
|
|
389
|
-
globals,
|
|
390
|
-
modules,
|
|
391
|
-
transforms,
|
|
392
|
-
__shimTransforms__,
|
|
393
|
-
Compartment,
|
|
394
|
-
});
|
|
395
|
-
|
|
396
|
-
await pendingJobsPromise;
|
|
397
|
-
|
|
398
|
-
// eslint-disable-next-line dot-notation
|
|
399
|
-
return compartment['import'](moduleSpecifier);
|
|
400
|
-
};
|
|
401
|
-
|
|
402
|
-
return { import: execute, sha512 };
|
|
403
|
-
};
|
|
404
85
|
|
|
405
86
|
/**
|
|
406
87
|
* @param {import('@endo/zip').ReadFn | ReadPowers} readPowers
|
|
@@ -408,27 +89,12 @@ export const parseArchive = async (
|
|
|
408
89
|
* @param {LoadArchiveOptions} [options]
|
|
409
90
|
* @returns {Promise<Application>}
|
|
410
91
|
*/
|
|
411
|
-
export const loadArchive = async (
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
)
|
|
416
|
-
|
|
417
|
-
const {
|
|
418
|
-
expectedSha512,
|
|
419
|
-
computeSourceLocation,
|
|
420
|
-
modules,
|
|
421
|
-
computeSourceMapLocation,
|
|
422
|
-
} = options;
|
|
423
|
-
const archiveBytes = await read(archiveLocation);
|
|
424
|
-
return parseArchive(archiveBytes, archiveLocation, {
|
|
425
|
-
computeSha512,
|
|
426
|
-
expectedSha512,
|
|
427
|
-
computeSourceLocation,
|
|
428
|
-
modules,
|
|
429
|
-
computeSourceMapLocation,
|
|
430
|
-
});
|
|
431
|
-
};
|
|
92
|
+
export const loadArchive = async (readPowers, archiveLocation, options) =>
|
|
93
|
+
loadArchiveLite(
|
|
94
|
+
readPowers,
|
|
95
|
+
archiveLocation,
|
|
96
|
+
assignParserForLanguage(options),
|
|
97
|
+
);
|
|
432
98
|
|
|
433
99
|
/**
|
|
434
100
|
* @param {import('@endo/zip').ReadFn | ReadPowers} readPowers
|
|
@@ -436,7 +102,9 @@ export const loadArchive = async (
|
|
|
436
102
|
* @param {ExecuteOptions & LoadArchiveOptions} options
|
|
437
103
|
* @returns {Promise<object>}
|
|
438
104
|
*/
|
|
439
|
-
export const importArchive = async (readPowers, archiveLocation, options) =>
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
105
|
+
export const importArchive = async (readPowers, archiveLocation, options) =>
|
|
106
|
+
importArchiveLite(
|
|
107
|
+
readPowers,
|
|
108
|
+
archiveLocation,
|
|
109
|
+
assignParserForLanguage(options),
|
|
110
|
+
);
|
package/src/import-hook.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"import-hook.d.ts","sourceRoot":"","sources":["import-hook.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"import-hook.d.ts","sourceRoot":"","sources":["import-hook.js"],"names":[],"mappings":"AA4EO,8EAJJ;IAAqC,OAAO,GAApC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,YAAC;IACU,oBAAoB,GAAlD,oBAAoB,YAAC;CAC7B,GAAU,oBAAoB,GAAC,SAAS,CA0B1C;AAuBM,gDApBI,MAAM,GAAC,UAAU,gBACjB,MAAM,qKAEd;IAA0B,OAAO;IACuB,sBAAsB;IACpD,WAAW;IACZ,aAAa;IACN,cAAc;IAOtB,oBAAoB,EAApC,MAAM;IACU,oBAAoB,EAApC,MAAM;IACyB,oBAAoB;IACN,aAAa;CAClE,GAAU,eAAe,CAuR3B;0CA7XuC,YAAY;4BAN1B,YAAY;gCACR,YAAY;6BAEf,YAAY;2CACE,YAAY;4BAF3B,YAAY;qCAGH,YAAY"}
|
package/src/import-hook.js
CHANGED
|
@@ -1,17 +1,22 @@
|
|
|
1
|
+
/* Provides the implementation of each compartment's `importHook` when using
|
|
2
|
+
* `import.js`, `import-lite.js`, `archive.js`, or `archive-lite.js`.
|
|
3
|
+
* However, `import-archive.js` and `import-archive-lite.js` use their own variant.
|
|
4
|
+
*
|
|
5
|
+
* For building archives, these import hooks create a table of all the modules
|
|
6
|
+
* in a "working set" of transitive dependencies.
|
|
7
|
+
*/
|
|
8
|
+
|
|
1
9
|
// @ts-check
|
|
2
10
|
|
|
3
11
|
/** @import {ImportHook} from 'ses' */
|
|
4
12
|
/** @import {StaticModuleType} from 'ses' */
|
|
5
13
|
/** @import {RedirectStaticModuleInterface} from 'ses' */
|
|
6
|
-
/** @import {ThirdPartyStaticModuleInterface} from 'ses' */
|
|
7
14
|
/** @import {ReadFn} from './types.js' */
|
|
8
15
|
/** @import {ReadPowers} from './types.js' */
|
|
9
16
|
/** @import {HashFn} from './types.js' */
|
|
10
17
|
/** @import {Sources} from './types.js' */
|
|
11
|
-
/** @import {CompartmentSources} from './types.js' */
|
|
12
18
|
/** @import {CompartmentDescriptor} from './types.js' */
|
|
13
19
|
/** @import {ImportHookMaker} from './types.js' */
|
|
14
|
-
/** @import {DeferredAttenuatorsProvider} from './types.js' */
|
|
15
20
|
/** @import {ExitModuleImportHook} from './types.js' */
|
|
16
21
|
|
|
17
22
|
import { attenuateModuleHook, enforceModulePolicy } from './policy.js';
|
|
@@ -204,6 +209,7 @@ export const makeImportHookMaker = (
|
|
|
204
209
|
|
|
205
210
|
/** @type {ImportHook} */
|
|
206
211
|
const importHook = async moduleSpecifier => {
|
|
212
|
+
await null;
|
|
207
213
|
compartmentDescriptor.retained = true;
|
|
208
214
|
|
|
209
215
|
// per-module:
|
|
@@ -316,6 +322,7 @@ export const makeImportHookMaker = (
|
|
|
316
322
|
(nextSourceMapObject => {
|
|
317
323
|
sourceMap = JSON.stringify(nextSourceMapObject);
|
|
318
324
|
}),
|
|
325
|
+
compartmentDescriptor,
|
|
319
326
|
},
|
|
320
327
|
);
|
|
321
328
|
const {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export function loadFromMap(readPowers: ReadFn | ReadPowers, compartmentMap: CompartmentMapDescriptor, options?: import("./types.js").ArchiveOptions | undefined): Promise<Application>;
|
|
2
|
+
export function importFromMap(readPowers: ReadFn | ReadPowers, compartmentMap: CompartmentMapDescriptor, options?: ImportLocationOptions | undefined): Promise<SomeObject>;
|
|
3
|
+
import type { ReadFn } from './types.js';
|
|
4
|
+
import type { ReadPowers } from './types.js';
|
|
5
|
+
import type { CompartmentMapDescriptor } from './types.js';
|
|
6
|
+
import type { Application } from './types.js';
|
|
7
|
+
import type { ImportLocationOptions } from './types.js';
|
|
8
|
+
import type { SomeObject } from './types.js';
|
|
9
|
+
//# sourceMappingURL=import-lite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"import-lite.d.ts","sourceRoot":"","sources":["import-lite.js"],"names":[],"mappings":"AA0CO,wCALI,MAAM,GAAG,UAAU,kBACnB,wBAAwB,8DAEtB,OAAO,CAAC,WAAW,CAAC,CAgEhC;AASM,0CANI,MAAM,GAAG,UAAU,kBACnB,wBAAwB,gDAEtB,OAAO,CAAC,UAAU,CAAC,CAU/B;4BAhGyB,YAAY;gCACR,YAAY;8CANE,YAAY;iCACzB,YAAY;2CACF,YAAY;gCAKvB,YAAY"}
|