@nocobase/plugin-flow-engine 2.0.0-alpha.2
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/LICENSE +661 -0
- package/README.md +29 -0
- package/build.config.ts +22 -0
- package/client.d.ts +2 -0
- package/client.js +1 -0
- package/dist/client/index.d.ts +15 -0
- package/dist/client/index.js +10 -0
- package/dist/externalVersion.js +21 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +48 -0
- package/dist/locale/en-US.json +61 -0
- package/dist/locale/index.d.ts +141 -0
- package/dist/locale/index.js +79 -0
- package/dist/locale/zh-CN.json +61 -0
- package/dist/node_modules/ses/LICENSE +201 -0
- package/dist/node_modules/ses/LICENSE-aura +16 -0
- package/dist/node_modules/ses/LICENSE-caja +13 -0
- package/dist/node_modules/ses/LICENSE-corejs +19 -0
- package/dist/node_modules/ses/LICENSE-v8 +9 -0
- package/dist/node_modules/ses/assert-shim.js +1 -0
- package/dist/node_modules/ses/compartment-shim.js +1 -0
- package/dist/node_modules/ses/console-shim.js +1 -0
- package/dist/node_modules/ses/dist/lockdown.cjs +13912 -0
- package/dist/node_modules/ses/dist/lockdown.umd.js +13912 -0
- package/dist/node_modules/ses/dist/lockdown.umd.min.js +1 -0
- package/dist/node_modules/ses/dist/ses-hermes.cjs +13912 -0
- package/dist/node_modules/ses/dist/ses.cjs +1 -0
- package/dist/node_modules/ses/dist/ses.umd.js +13912 -0
- package/dist/node_modules/ses/dist/ses.umd.min.js +1 -0
- package/dist/node_modules/ses/dist/types.d.cts +606 -0
- package/dist/node_modules/ses/index.js +18 -0
- package/dist/node_modules/ses/lockdown-shim.js +1 -0
- package/dist/node_modules/ses/lockdown.js +1 -0
- package/dist/node_modules/ses/package.json +1 -0
- package/dist/node_modules/ses/src/assert-shim.js +4 -0
- package/dist/node_modules/ses/src/assert-sloppy-mode.js +11 -0
- package/dist/node_modules/ses/src/cauterize-property.js +69 -0
- package/dist/node_modules/ses/src/commons.js +425 -0
- package/dist/node_modules/ses/src/compartment-evaluate.js +93 -0
- package/dist/node_modules/ses/src/compartment-shim.js +22 -0
- package/dist/node_modules/ses/src/compartment.js +477 -0
- package/dist/node_modules/ses/src/console-shim.js +50 -0
- package/dist/node_modules/ses/src/enable-property-overrides.js +211 -0
- package/dist/node_modules/ses/src/enablements.js +244 -0
- package/dist/node_modules/ses/src/error/assert.js +584 -0
- package/dist/node_modules/ses/src/error/console.js +541 -0
- package/dist/node_modules/ses/src/error/fatal-assert.js +54 -0
- package/dist/node_modules/ses/src/error/internal-types.js +98 -0
- package/dist/node_modules/ses/src/error/note-log-args.js +77 -0
- package/dist/node_modules/ses/src/error/stringify-utils.js +195 -0
- package/dist/node_modules/ses/src/error/tame-console.js +197 -0
- package/dist/node_modules/ses/src/error/tame-error-constructor.js +284 -0
- package/dist/node_modules/ses/src/error/tame-v8-error-constructor.js +386 -0
- package/dist/node_modules/ses/src/error/types.js +59 -0
- package/dist/node_modules/ses/src/error/unhandled-rejection.js +122 -0
- package/dist/node_modules/ses/src/eval-scope.js +89 -0
- package/dist/node_modules/ses/src/get-anonymous-intrinsics.js +181 -0
- package/dist/node_modules/ses/src/get-source-url.js +50 -0
- package/dist/node_modules/ses/src/global-object.js +175 -0
- package/dist/node_modules/ses/src/intrinsics.js +192 -0
- package/dist/node_modules/ses/src/lockdown-shim.js +37 -0
- package/dist/node_modules/ses/src/lockdown.js +558 -0
- package/dist/node_modules/ses/src/make-eval-function.js +28 -0
- package/dist/node_modules/ses/src/make-evaluate.js +110 -0
- package/dist/node_modules/ses/src/make-function-constructor.js +79 -0
- package/dist/node_modules/ses/src/make-hardener.js +275 -0
- package/dist/node_modules/ses/src/make-safe-evaluator.js +112 -0
- package/dist/node_modules/ses/src/module-instance.js +497 -0
- package/dist/node_modules/ses/src/module-link.js +159 -0
- package/dist/node_modules/ses/src/module-load.js +719 -0
- package/dist/node_modules/ses/src/module-proxy.js +200 -0
- package/dist/node_modules/ses/src/permits-intrinsics.js +291 -0
- package/dist/node_modules/ses/src/permits.js +1761 -0
- package/dist/node_modules/ses/src/reporting-types.d.ts +13 -0
- package/dist/node_modules/ses/src/reporting.js +105 -0
- package/dist/node_modules/ses/src/scope-constants.js +180 -0
- package/dist/node_modules/ses/src/shim-arraybuffer-transfer.js +85 -0
- package/dist/node_modules/ses/src/sloppy-globals-scope-terminator.js +61 -0
- package/dist/node_modules/ses/src/strict-scope-terminator.js +99 -0
- package/dist/node_modules/ses/src/tame-date-constructor.js +127 -0
- package/dist/node_modules/ses/src/tame-domains.js +41 -0
- package/dist/node_modules/ses/src/tame-faux-data-properties.js +210 -0
- package/dist/node_modules/ses/src/tame-function-constructors.js +140 -0
- package/dist/node_modules/ses/src/tame-function-tostring.js +50 -0
- package/dist/node_modules/ses/src/tame-harden.js +29 -0
- package/dist/node_modules/ses/src/tame-locale-methods.js +78 -0
- package/dist/node_modules/ses/src/tame-math-object.js +41 -0
- package/dist/node_modules/ses/src/tame-module-source.js +51 -0
- package/dist/node_modules/ses/src/tame-regenerator-runtime.js +29 -0
- package/dist/node_modules/ses/src/tame-regexp-constructor.js +65 -0
- package/dist/node_modules/ses/src/tame-symbol-constructor.js +64 -0
- package/dist/node_modules/ses/src/transforms.js +267 -0
- package/dist/node_modules/ses/tools.js +25 -0
- package/dist/node_modules/ses/types.d.ts +606 -0
- package/dist/server/actions/ui-schema-action.d.ts +27 -0
- package/dist/server/actions/ui-schema-action.js +118 -0
- package/dist/server/collections/flowModelTreePath.d.ts +11 -0
- package/dist/server/collections/flowModelTreePath.js +74 -0
- package/dist/server/collections/flowModels.d.ts +11 -0
- package/dist/server/collections/flowModels.js +57 -0
- package/dist/server/collections/flowsql.d.ts +10 -0
- package/dist/server/collections/flowsql.js +51 -0
- package/dist/server/dao/ui_schema_node_dao.d.ts +26 -0
- package/dist/server/dao/ui_schema_node_dao.js +24 -0
- package/dist/server/helper.d.ts +8 -0
- package/dist/server/helper.js +9 -0
- package/dist/server/index.d.ts +9 -0
- package/dist/server/index.js +42 -0
- package/dist/server/model.d.ts +12 -0
- package/dist/server/model.js +38 -0
- package/dist/server/plugin.d.ts +26 -0
- package/dist/server/plugin.js +270 -0
- package/dist/server/repository.d.ts +116 -0
- package/dist/server/repository.js +1209 -0
- package/dist/server/server.d.ts +16 -0
- package/dist/server/server.js +198 -0
- package/dist/server/template/contexts.d.ts +73 -0
- package/dist/server/template/contexts.js +233 -0
- package/dist/server/template/resolver.d.ts +30 -0
- package/dist/server/template/resolver.js +225 -0
- package/dist/server/variables/registry.d.ts +42 -0
- package/dist/server/variables/registry.js +299 -0
- package/package.json +28 -0
- package/server.d.ts +2 -0
- package/server.js +1 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
/** @import {GenericErrorConstructor, AssertMakeErrorOptions, DetailsToken, StringablePayload} from '../../types.js' */
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @typedef {object} VirtualConsole
|
|
7
|
+
* @property {Console['debug']} debug
|
|
8
|
+
* @property {Console['log']} log
|
|
9
|
+
* @property {Console['info']} info
|
|
10
|
+
* @property {Console['warn']} warn
|
|
11
|
+
* @property {Console['error']} error
|
|
12
|
+
*
|
|
13
|
+
* @property {Console['trace']} trace
|
|
14
|
+
* @property {Console['dirxml']} dirxml
|
|
15
|
+
* @property {Console['group']} group
|
|
16
|
+
* @property {Console['groupCollapsed']} groupCollapsed
|
|
17
|
+
*
|
|
18
|
+
* @property {Console['assert']} assert
|
|
19
|
+
* @property {Console['timeLog']} timeLog
|
|
20
|
+
*
|
|
21
|
+
* @property {Console['clear']} clear
|
|
22
|
+
* @property {Console['count']} count
|
|
23
|
+
* @property {Console['countReset']} countReset
|
|
24
|
+
* @property {Console['dir']} dir
|
|
25
|
+
* @property {Console['groupEnd']} groupEnd
|
|
26
|
+
*
|
|
27
|
+
* @property {Console['table']} table
|
|
28
|
+
* @property {Console['time']} time
|
|
29
|
+
* @property {Console['timeEnd']} timeEnd
|
|
30
|
+
* @property {Console['timeStamp']} timeStamp
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
/* This is deliberately *not* JSDoc, it is a regular comment.
|
|
34
|
+
*
|
|
35
|
+
* TODO: We'd like to add the following properties to the above
|
|
36
|
+
* VirtualConsole, but they currently cause conflicts where
|
|
37
|
+
* some Typescript implementations don't have these properties
|
|
38
|
+
* on the Console type.
|
|
39
|
+
*
|
|
40
|
+
* @property {Console['profile']} profile
|
|
41
|
+
* @property {Console['profileEnd']} profileEnd
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @typedef {'debug' | 'log' | 'info' | 'warn' | 'error'} LogSeverity
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @typedef ConsoleFilter
|
|
50
|
+
* @property {(severity: LogSeverity) => boolean} canLog
|
|
51
|
+
*/
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @callback FilterConsole
|
|
55
|
+
* @param {VirtualConsole} baseConsole
|
|
56
|
+
* @param {ConsoleFilter} filter
|
|
57
|
+
* @param {string} [topic]
|
|
58
|
+
* @returns {VirtualConsole}
|
|
59
|
+
*/
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import {
|
|
3
|
+
FinalizationRegistry,
|
|
4
|
+
Map,
|
|
5
|
+
mapGet,
|
|
6
|
+
mapDelete,
|
|
7
|
+
WeakMap,
|
|
8
|
+
mapSet,
|
|
9
|
+
finalizationRegistryRegister,
|
|
10
|
+
weakmapSet,
|
|
11
|
+
weakmapGet,
|
|
12
|
+
mapEntries,
|
|
13
|
+
mapHas,
|
|
14
|
+
} from '../commons.js';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Create rejection-tracking machinery compatible with Node.js and browsers.
|
|
18
|
+
*
|
|
19
|
+
* Note that modern browsers *prevent* access to the 'unhandledrejection' and
|
|
20
|
+
* 'rejectionhandled' events needed:
|
|
21
|
+
* - in cross-origin mode, like when served from file://
|
|
22
|
+
* - in the browser console (interactively typed-in code)
|
|
23
|
+
* - in the debugger
|
|
24
|
+
*
|
|
25
|
+
* Then, they just look like: `Uncaught (in promise) Error: ...` and don't
|
|
26
|
+
* implement the machinery.
|
|
27
|
+
*
|
|
28
|
+
* The solution is to serve your web page from an http:// or https:// web server
|
|
29
|
+
* and execute actual code.
|
|
30
|
+
*
|
|
31
|
+
* @param {(reason: unknown) => void} reportReason report the reason for an
|
|
32
|
+
* unhandled rejection.
|
|
33
|
+
*/
|
|
34
|
+
export const makeRejectionHandlers = reportReason => {
|
|
35
|
+
if (FinalizationRegistry === undefined) {
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** @typedef {number} ReasonId */
|
|
40
|
+
let lastReasonId = 0;
|
|
41
|
+
|
|
42
|
+
/** @type {Map<ReasonId, unknown>} */
|
|
43
|
+
const idToReason = new Map();
|
|
44
|
+
|
|
45
|
+
/** @type {(() => void) | undefined} */
|
|
46
|
+
let cancelChecking;
|
|
47
|
+
|
|
48
|
+
const removeReasonId = reasonId => {
|
|
49
|
+
mapDelete(idToReason, reasonId);
|
|
50
|
+
if (cancelChecking && idToReason.size === 0) {
|
|
51
|
+
// No more unhandled rejections to check, just cancel the check.
|
|
52
|
+
cancelChecking();
|
|
53
|
+
cancelChecking = undefined;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
/** @type {WeakMap<Promise, ReasonId>} */
|
|
58
|
+
const promiseToReasonId = new WeakMap();
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Clean up and report the reason for a GCed unhandled rejection.
|
|
62
|
+
*
|
|
63
|
+
* @param {ReasonId} heldReasonId
|
|
64
|
+
*/
|
|
65
|
+
const finalizeDroppedPromise = heldReasonId => {
|
|
66
|
+
if (mapHas(idToReason, heldReasonId)) {
|
|
67
|
+
const reason = mapGet(idToReason, heldReasonId);
|
|
68
|
+
removeReasonId(heldReasonId);
|
|
69
|
+
reportReason(reason);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
/** @type {FinalizationRegistry<ReasonId>} */
|
|
74
|
+
const promiseToReason = new FinalizationRegistry(finalizeDroppedPromise);
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Track a rejected promise and its corresponding reason if there is no
|
|
78
|
+
* rejection handler synchronously attached.
|
|
79
|
+
*
|
|
80
|
+
* @param {unknown} reason
|
|
81
|
+
* @param {Promise} pr
|
|
82
|
+
*/
|
|
83
|
+
const unhandledRejectionHandler = (reason, pr) => {
|
|
84
|
+
lastReasonId += 1;
|
|
85
|
+
const reasonId = lastReasonId;
|
|
86
|
+
|
|
87
|
+
// Update bookkeeping.
|
|
88
|
+
mapSet(idToReason, reasonId, reason);
|
|
89
|
+
weakmapSet(promiseToReasonId, pr, reasonId);
|
|
90
|
+
finalizationRegistryRegister(promiseToReason, pr, reasonId, pr);
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Deal with the addition of a handler to a previously rejected promise.
|
|
95
|
+
*
|
|
96
|
+
* Just remove it from our list. Let the FinalizationRegistry or
|
|
97
|
+
* processTermination report any GCed unhandled rejected promises.
|
|
98
|
+
*
|
|
99
|
+
* @param {Promise} pr
|
|
100
|
+
*/
|
|
101
|
+
const rejectionHandledHandler = pr => {
|
|
102
|
+
const reasonId = weakmapGet(promiseToReasonId, pr);
|
|
103
|
+
removeReasonId(reasonId);
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Report all the unhandled rejections, now that we are abruptly terminating
|
|
108
|
+
* the agent cluster.
|
|
109
|
+
*/
|
|
110
|
+
const processTerminationHandler = () => {
|
|
111
|
+
for (const [reasonId, reason] of mapEntries(idToReason)) {
|
|
112
|
+
removeReasonId(reasonId);
|
|
113
|
+
reportReason(reason);
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
return {
|
|
118
|
+
rejectionHandledHandler,
|
|
119
|
+
unhandledRejectionHandler,
|
|
120
|
+
processTerminationHandler,
|
|
121
|
+
};
|
|
122
|
+
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { FERAL_EVAL, create, defineProperties, freeze } from './commons.js';
|
|
2
|
+
|
|
3
|
+
import { assert } from './error/assert.js';
|
|
4
|
+
|
|
5
|
+
const { Fail } = assert;
|
|
6
|
+
|
|
7
|
+
// We attempt to frustrate stack bumping attacks on the safe evaluator
|
|
8
|
+
// (`make-safe-evaluator.js`).
|
|
9
|
+
// A stack bumping attack forces an API call to throw a stack overflow
|
|
10
|
+
// `RangeError` at an inopportune time.
|
|
11
|
+
// The attacker arranges for the stack to be sufficiently deep that the API
|
|
12
|
+
// consumes exactly enough stack frames to throw an exception.
|
|
13
|
+
//
|
|
14
|
+
// For the safe evaluator, an exception thrown between adding and then deleting
|
|
15
|
+
// `eval` on `evalScope` could leak the real `eval` to an attacker's lexical
|
|
16
|
+
// scope.
|
|
17
|
+
// This would be sufficiently disastrous that we guard against it twice.
|
|
18
|
+
// First, we delete `eval` from `evalScope` immediately before rendering it to
|
|
19
|
+
// the guest program's lexical scope.
|
|
20
|
+
//
|
|
21
|
+
// If the attacker manages to arrange for `eval` to throw an exception after we
|
|
22
|
+
// call `allowNextEvalToBeUnsafe` but before the guest program accesses `eval`,
|
|
23
|
+
// it would be able to access `eval` once more in its own code.
|
|
24
|
+
// Although they could do no harm with a direct `eval`, they would be able to
|
|
25
|
+
// escape to the true global scope with an indirect `eval`.
|
|
26
|
+
//
|
|
27
|
+
// prepareStack(depth, () => {
|
|
28
|
+
// (eval)('');
|
|
29
|
+
// });
|
|
30
|
+
// const unsafeEval = (eval);
|
|
31
|
+
// const safeEval = (eval);
|
|
32
|
+
// const realGlobal = unsafeEval('globalThis');
|
|
33
|
+
//
|
|
34
|
+
// To protect against that case, we also delete `eval` from the `evalScope` in
|
|
35
|
+
// a `finally` block surrounding the call to the safe evaluator.
|
|
36
|
+
// The only way to reach this case is if `eval` remains on `evalScope` due to
|
|
37
|
+
// an attack, so we assume that attack would have have invalided our isolation
|
|
38
|
+
// and revoke all future access to the evaluator.
|
|
39
|
+
//
|
|
40
|
+
// To defeat a stack bumping attack, we must use fewer stack frames to recover
|
|
41
|
+
// in that `finally` block than we used in the `try` block.
|
|
42
|
+
// We have no reliable guarantees about how many stack frames a block of
|
|
43
|
+
// JavaScript will consume.
|
|
44
|
+
// Function inlining, tail-call optimization, variations in the size of a stack
|
|
45
|
+
// frame, and block scopes may affect the depth of the stack.
|
|
46
|
+
// The only number of acceptable stack frames to use in the finally block is
|
|
47
|
+
// zero.
|
|
48
|
+
// We only use property assignment and deletion in the safe evaluator's
|
|
49
|
+
// `finally` block.
|
|
50
|
+
// We use `delete evalScope.eval` to withhold the evaluator.
|
|
51
|
+
// We assign an envelope object over `evalScopeKit.revoked` to revoke the
|
|
52
|
+
// evaluator.
|
|
53
|
+
//
|
|
54
|
+
// This is why we supply a meaningfully named function for
|
|
55
|
+
// `allowNextEvalToBeUnsafe` but do not provide a corresponding
|
|
56
|
+
// `revokeAccessToUnsafeEval` or even simply `revoke`.
|
|
57
|
+
// These recovery routines are expressed inline in the safe evaluator.
|
|
58
|
+
|
|
59
|
+
export const makeEvalScopeKit = () => {
|
|
60
|
+
const evalScope = create(null);
|
|
61
|
+
const oneTimeEvalProperties = freeze({
|
|
62
|
+
eval: {
|
|
63
|
+
get() {
|
|
64
|
+
delete evalScope.eval;
|
|
65
|
+
return FERAL_EVAL;
|
|
66
|
+
},
|
|
67
|
+
enumerable: false,
|
|
68
|
+
configurable: true,
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
const evalScopeKit = {
|
|
73
|
+
evalScope,
|
|
74
|
+
allowNextEvalToBeUnsafe() {
|
|
75
|
+
const { revoked } = evalScopeKit;
|
|
76
|
+
if (revoked !== null) {
|
|
77
|
+
Fail`a handler did not reset allowNextEvalToBeUnsafe ${revoked.err}`;
|
|
78
|
+
}
|
|
79
|
+
// Allow next reference to eval produce the unsafe FERAL_EVAL.
|
|
80
|
+
// We avoid defineProperty because it consumes an extra stack frame taming
|
|
81
|
+
// its return value.
|
|
82
|
+
defineProperties(evalScope, oneTimeEvalProperties);
|
|
83
|
+
},
|
|
84
|
+
/** @type {null | { err: any }} */
|
|
85
|
+
revoked: null,
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
return evalScopeKit;
|
|
89
|
+
};
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FERAL_FUNCTION,
|
|
3
|
+
Float32Array,
|
|
4
|
+
Map,
|
|
5
|
+
Set,
|
|
6
|
+
String,
|
|
7
|
+
getOwnPropertyDescriptor,
|
|
8
|
+
getPrototypeOf,
|
|
9
|
+
iterateArray,
|
|
10
|
+
iterateMap,
|
|
11
|
+
iterateSet,
|
|
12
|
+
iterateString,
|
|
13
|
+
matchAllRegExp,
|
|
14
|
+
matchAllSymbol,
|
|
15
|
+
regexpPrototype,
|
|
16
|
+
globalThis,
|
|
17
|
+
assign,
|
|
18
|
+
AsyncGeneratorFunctionInstance,
|
|
19
|
+
ArrayBuffer,
|
|
20
|
+
} from './commons.js';
|
|
21
|
+
import { InertCompartment } from './compartment.js';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Object.getConstructorOf()
|
|
25
|
+
* Helper function to improve readability, similar to Object.getPrototypeOf().
|
|
26
|
+
*
|
|
27
|
+
* @param {object} obj
|
|
28
|
+
*/
|
|
29
|
+
function getConstructorOf(obj) {
|
|
30
|
+
return getPrototypeOf(obj).constructor;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// getAnonymousIntrinsics uses a utility function to construct an arguments
|
|
34
|
+
// object, since it cannot have one of its own and also be a const export.
|
|
35
|
+
function makeArguments() {
|
|
36
|
+
// eslint-disable-next-line prefer-rest-params
|
|
37
|
+
return arguments;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* getAnonymousIntrinsics()
|
|
42
|
+
* Get the intrinsics not otherwise reachable by named own property
|
|
43
|
+
* traversal from the global object.
|
|
44
|
+
*
|
|
45
|
+
* @returns {object}
|
|
46
|
+
*/
|
|
47
|
+
export const getAnonymousIntrinsics = () => {
|
|
48
|
+
const InertFunction = FERAL_FUNCTION.prototype.constructor;
|
|
49
|
+
|
|
50
|
+
// 9.2.4.1 %ThrowTypeError%
|
|
51
|
+
|
|
52
|
+
const argsCalleeDesc = getOwnPropertyDescriptor(makeArguments(), 'callee');
|
|
53
|
+
const ThrowTypeError = argsCalleeDesc && argsCalleeDesc.get;
|
|
54
|
+
|
|
55
|
+
// 21.1.5.2 The %StringIteratorPrototype% Object
|
|
56
|
+
|
|
57
|
+
// eslint-disable-next-line no-new-wrappers
|
|
58
|
+
const StringIteratorObject = iterateString(new String());
|
|
59
|
+
const StringIteratorPrototype = getPrototypeOf(StringIteratorObject);
|
|
60
|
+
|
|
61
|
+
// 21.2.7.1 The %RegExpStringIteratorPrototype% Object
|
|
62
|
+
const RegExpStringIterator =
|
|
63
|
+
regexpPrototype[matchAllSymbol] && matchAllRegExp(/./);
|
|
64
|
+
const RegExpStringIteratorPrototype =
|
|
65
|
+
RegExpStringIterator && getPrototypeOf(RegExpStringIterator);
|
|
66
|
+
|
|
67
|
+
// 22.1.5.2 The %ArrayIteratorPrototype% Object
|
|
68
|
+
|
|
69
|
+
// eslint-disable-next-line no-array-constructor
|
|
70
|
+
const ArrayIteratorObject = iterateArray([]);
|
|
71
|
+
const ArrayIteratorPrototype = getPrototypeOf(ArrayIteratorObject);
|
|
72
|
+
|
|
73
|
+
// 22.2.1 The %TypedArray% Intrinsic Object
|
|
74
|
+
|
|
75
|
+
const TypedArray = getPrototypeOf(Float32Array);
|
|
76
|
+
|
|
77
|
+
// 23.1.5.2 The %MapIteratorPrototype% Object
|
|
78
|
+
|
|
79
|
+
const MapIteratorObject = iterateMap(new Map());
|
|
80
|
+
const MapIteratorPrototype = getPrototypeOf(MapIteratorObject);
|
|
81
|
+
|
|
82
|
+
// 23.2.5.2 The %SetIteratorPrototype% Object
|
|
83
|
+
|
|
84
|
+
const SetIteratorObject = iterateSet(new Set());
|
|
85
|
+
const SetIteratorPrototype = getPrototypeOf(SetIteratorObject);
|
|
86
|
+
|
|
87
|
+
// 25.1.2 The %IteratorPrototype% Object
|
|
88
|
+
|
|
89
|
+
const IteratorPrototype = getPrototypeOf(ArrayIteratorPrototype);
|
|
90
|
+
|
|
91
|
+
// 25.2.1 The GeneratorFunction Constructor
|
|
92
|
+
|
|
93
|
+
// eslint-disable-next-line no-empty-function
|
|
94
|
+
function* GeneratorFunctionInstance() {}
|
|
95
|
+
const GeneratorFunction = getConstructorOf(GeneratorFunctionInstance);
|
|
96
|
+
|
|
97
|
+
// 25.2.3 Properties of the GeneratorFunction Prototype Object
|
|
98
|
+
|
|
99
|
+
const Generator = GeneratorFunction.prototype;
|
|
100
|
+
|
|
101
|
+
// 25.7.1 The AsyncFunction Constructor
|
|
102
|
+
|
|
103
|
+
// eslint-disable-next-line no-empty-function
|
|
104
|
+
async function AsyncFunctionInstance() {}
|
|
105
|
+
const AsyncFunction = getConstructorOf(AsyncFunctionInstance);
|
|
106
|
+
|
|
107
|
+
const intrinsics = {
|
|
108
|
+
'%InertFunction%': InertFunction,
|
|
109
|
+
'%ArrayIteratorPrototype%': ArrayIteratorPrototype,
|
|
110
|
+
'%InertAsyncFunction%': AsyncFunction,
|
|
111
|
+
'%Generator%': Generator,
|
|
112
|
+
'%InertGeneratorFunction%': GeneratorFunction,
|
|
113
|
+
'%IteratorPrototype%': IteratorPrototype,
|
|
114
|
+
'%MapIteratorPrototype%': MapIteratorPrototype,
|
|
115
|
+
'%RegExpStringIteratorPrototype%': RegExpStringIteratorPrototype,
|
|
116
|
+
'%SetIteratorPrototype%': SetIteratorPrototype,
|
|
117
|
+
'%StringIteratorPrototype%': StringIteratorPrototype,
|
|
118
|
+
'%ThrowTypeError%': ThrowTypeError,
|
|
119
|
+
'%TypedArray%': TypedArray,
|
|
120
|
+
'%InertCompartment%': InertCompartment,
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
if (AsyncGeneratorFunctionInstance !== undefined) {
|
|
124
|
+
// 25.3.1 The AsyncGeneratorFunction Constructor
|
|
125
|
+
|
|
126
|
+
const AsyncGeneratorFunction = getConstructorOf(
|
|
127
|
+
AsyncGeneratorFunctionInstance,
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
// 25.3.2.2 AsyncGeneratorFunction.prototype
|
|
131
|
+
const AsyncGenerator = AsyncGeneratorFunction.prototype;
|
|
132
|
+
// 25.5.1 Properties of the AsyncGenerator Prototype Object
|
|
133
|
+
const AsyncGeneratorPrototype = AsyncGenerator.prototype;
|
|
134
|
+
const AsyncIteratorPrototype = getPrototypeOf(AsyncGeneratorPrototype);
|
|
135
|
+
|
|
136
|
+
assign(intrinsics, {
|
|
137
|
+
'%AsyncGenerator%': AsyncGenerator,
|
|
138
|
+
'%InertAsyncGeneratorFunction%': AsyncGeneratorFunction,
|
|
139
|
+
'%AsyncGeneratorPrototype%': AsyncGeneratorPrototype,
|
|
140
|
+
'%AsyncIteratorPrototype%': AsyncIteratorPrototype,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (globalThis.Iterator) {
|
|
145
|
+
intrinsics['%IteratorHelperPrototype%'] = getPrototypeOf(
|
|
146
|
+
// eslint-disable-next-line @endo/no-polymorphic-call
|
|
147
|
+
globalThis.Iterator.from([]).take(0),
|
|
148
|
+
);
|
|
149
|
+
intrinsics['%WrapForValidIteratorPrototype%'] = getPrototypeOf(
|
|
150
|
+
// eslint-disable-next-line @endo/no-polymorphic-call
|
|
151
|
+
globalThis.Iterator.from({
|
|
152
|
+
next() {
|
|
153
|
+
return { value: undefined };
|
|
154
|
+
},
|
|
155
|
+
}),
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (globalThis.AsyncIterator) {
|
|
160
|
+
intrinsics['%AsyncIteratorHelperPrototype%'] = getPrototypeOf(
|
|
161
|
+
// eslint-disable-next-line @endo/no-polymorphic-call
|
|
162
|
+
globalThis.AsyncIterator.from([]).take(0),
|
|
163
|
+
);
|
|
164
|
+
intrinsics['%WrapForValidAsyncIteratorPrototype%'] = getPrototypeOf(
|
|
165
|
+
// eslint-disable-next-line @endo/no-polymorphic-call
|
|
166
|
+
globalThis.AsyncIterator.from({ next() {} }),
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const ab = new ArrayBuffer(0);
|
|
171
|
+
// @ts-expect-error TODO How do I add sliceToImmutable to ArrayBuffer type?
|
|
172
|
+
// eslint-disable-next-line @endo/no-polymorphic-call
|
|
173
|
+
const iab = ab.sliceToImmutable();
|
|
174
|
+
const iabProto = getPrototypeOf(iab);
|
|
175
|
+
if (iabProto !== ArrayBuffer.prototype) {
|
|
176
|
+
// In a native implementation, these will be the same prototype
|
|
177
|
+
intrinsics['%ImmutableArrayBufferPrototype%'] = iabProto;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return intrinsics;
|
|
181
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { FERAL_REG_EXP, regexpExec, stringSlice } from './commons.js';
|
|
2
|
+
|
|
3
|
+
// Captures a key and value of the form #key=value or @key=value
|
|
4
|
+
const sourceMetaEntryRegExp =
|
|
5
|
+
'\\s*[@#]\\s*([a-zA-Z][a-zA-Z0-9]*)\\s*=\\s*([^\\s\\*]*)';
|
|
6
|
+
// Captures either a one-line or multi-line comment containing
|
|
7
|
+
// one #key=value or @key=value.
|
|
8
|
+
// Produces two pairs of capture groups, but the initial two may be undefined.
|
|
9
|
+
// On account of the mechanics of regular expressions, scanning from the end
|
|
10
|
+
// does not allow us to capture every pair, so getSourceURL must capture and
|
|
11
|
+
// trim until there are no matching comments.
|
|
12
|
+
const sourceMetaEntriesRegExp = new FERAL_REG_EXP(
|
|
13
|
+
`(?:\\s*//${sourceMetaEntryRegExp}|/\\*${sourceMetaEntryRegExp}\\s*\\*/)\\s*$`,
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @param {string} src
|
|
18
|
+
*/
|
|
19
|
+
export const getSourceURL = src => {
|
|
20
|
+
let sourceURL = '<unknown>';
|
|
21
|
+
|
|
22
|
+
// Our regular expression matches the last one or two comments with key value
|
|
23
|
+
// pairs at the end of the source, avoiding a scan over the entire length of
|
|
24
|
+
// the string, but at the expense of being able to capture all the (key,
|
|
25
|
+
// value) pair meta comments at the end of the source, which may include
|
|
26
|
+
// sourceMapURL in addition to sourceURL.
|
|
27
|
+
// So, we sublimate the comments out of the source until no source or no
|
|
28
|
+
// comments remain.
|
|
29
|
+
while (src.length > 0) {
|
|
30
|
+
const match = regexpExec(sourceMetaEntriesRegExp, src);
|
|
31
|
+
if (match === null) {
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
src = stringSlice(src, 0, src.length - match[0].length);
|
|
35
|
+
|
|
36
|
+
// We skip $0 since it contains the entire match.
|
|
37
|
+
// The match contains four capture groups,
|
|
38
|
+
// two (key, value) pairs, the first of which
|
|
39
|
+
// may be undefined.
|
|
40
|
+
// On the off-chance someone put two sourceURL comments in their code with
|
|
41
|
+
// different commenting conventions, the latter has precedence.
|
|
42
|
+
if (match[3] === 'sourceURL') {
|
|
43
|
+
sourceURL = match[4];
|
|
44
|
+
} else if (match[1] === 'sourceURL') {
|
|
45
|
+
sourceURL = match[2];
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return sourceURL;
|
|
50
|
+
};
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import {
|
|
2
|
+
TypeError,
|
|
3
|
+
assign,
|
|
4
|
+
create,
|
|
5
|
+
defineProperty,
|
|
6
|
+
entries,
|
|
7
|
+
freeze,
|
|
8
|
+
hasOwn,
|
|
9
|
+
unscopablesSymbol,
|
|
10
|
+
} from './commons.js';
|
|
11
|
+
import { makeEvalFunction } from './make-eval-function.js';
|
|
12
|
+
import { makeFunctionConstructor } from './make-function-constructor.js';
|
|
13
|
+
import { constantProperties, universalPropertyNames } from './permits.js';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The host's ordinary global object is not provided by a `with` block, so
|
|
17
|
+
* assigning to Symbol.unscopables has no effect.
|
|
18
|
+
* Since this shim uses `with` blocks to create a confined lexical scope for
|
|
19
|
+
* guest programs, we cannot emulate the proper behavior.
|
|
20
|
+
* With this shim, assigning Symbol.unscopables causes the given lexical
|
|
21
|
+
* names to fall through to the terminal scope proxy.
|
|
22
|
+
* But, we can install this setter to prevent a program from proceding on
|
|
23
|
+
* this false assumption.
|
|
24
|
+
*
|
|
25
|
+
* @param {object} globalObject
|
|
26
|
+
*/
|
|
27
|
+
export const setGlobalObjectSymbolUnscopables = globalObject => {
|
|
28
|
+
defineProperty(
|
|
29
|
+
globalObject,
|
|
30
|
+
unscopablesSymbol,
|
|
31
|
+
freeze(
|
|
32
|
+
assign(create(null), {
|
|
33
|
+
set: freeze(() => {
|
|
34
|
+
throw TypeError(
|
|
35
|
+
`Cannot set Symbol.unscopables of a Compartment's globalThis`,
|
|
36
|
+
);
|
|
37
|
+
}),
|
|
38
|
+
enumerable: false,
|
|
39
|
+
configurable: false,
|
|
40
|
+
}),
|
|
41
|
+
),
|
|
42
|
+
);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* setGlobalObjectConstantProperties()
|
|
47
|
+
* Initializes a new global object using a process similar to ECMA specifications
|
|
48
|
+
* (SetDefaultGlobalBindings). This process is split between this function and
|
|
49
|
+
* `setGlobalObjectMutableProperties`.
|
|
50
|
+
*
|
|
51
|
+
* @param {object} globalObject
|
|
52
|
+
*/
|
|
53
|
+
export const setGlobalObjectConstantProperties = globalObject => {
|
|
54
|
+
for (const [name, constant] of entries(constantProperties)) {
|
|
55
|
+
defineProperty(globalObject, name, {
|
|
56
|
+
value: constant,
|
|
57
|
+
writable: false,
|
|
58
|
+
enumerable: false,
|
|
59
|
+
configurable: false,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* setGlobalObjectMutableProperties()
|
|
66
|
+
* Create new global object using a process similar to ECMA specifications
|
|
67
|
+
* (portions of SetRealmGlobalObject and SetDefaultGlobalBindings).
|
|
68
|
+
* `newGlobalPropertyNames` should be either `initialGlobalPropertyNames` or
|
|
69
|
+
* `sharedGlobalPropertyNames`.
|
|
70
|
+
*
|
|
71
|
+
* @param {object} globalObject
|
|
72
|
+
* @param {object} args
|
|
73
|
+
* @param {object} args.intrinsics
|
|
74
|
+
* @param {object} args.newGlobalPropertyNames
|
|
75
|
+
* @param {Function} args.makeCompartmentConstructor
|
|
76
|
+
* @param {(object) => void} args.markVirtualizedNativeFunction
|
|
77
|
+
* @param {Compartment} [args.parentCompartment]
|
|
78
|
+
*/
|
|
79
|
+
export const setGlobalObjectMutableProperties = (
|
|
80
|
+
globalObject,
|
|
81
|
+
{
|
|
82
|
+
intrinsics,
|
|
83
|
+
newGlobalPropertyNames,
|
|
84
|
+
makeCompartmentConstructor,
|
|
85
|
+
markVirtualizedNativeFunction,
|
|
86
|
+
parentCompartment,
|
|
87
|
+
},
|
|
88
|
+
) => {
|
|
89
|
+
for (const [name, intrinsicName] of entries(universalPropertyNames)) {
|
|
90
|
+
if (hasOwn(intrinsics, intrinsicName)) {
|
|
91
|
+
defineProperty(globalObject, name, {
|
|
92
|
+
value: intrinsics[intrinsicName],
|
|
93
|
+
writable: true,
|
|
94
|
+
enumerable: false,
|
|
95
|
+
configurable: true,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
for (const [name, intrinsicName] of entries(newGlobalPropertyNames)) {
|
|
101
|
+
if (hasOwn(intrinsics, intrinsicName)) {
|
|
102
|
+
defineProperty(globalObject, name, {
|
|
103
|
+
value: intrinsics[intrinsicName],
|
|
104
|
+
writable: true,
|
|
105
|
+
enumerable: false,
|
|
106
|
+
configurable: true,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const perCompartmentGlobals = {
|
|
112
|
+
globalThis: globalObject,
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
perCompartmentGlobals.Compartment = freeze(
|
|
116
|
+
makeCompartmentConstructor(
|
|
117
|
+
makeCompartmentConstructor,
|
|
118
|
+
intrinsics,
|
|
119
|
+
markVirtualizedNativeFunction,
|
|
120
|
+
{
|
|
121
|
+
parentCompartment,
|
|
122
|
+
enforceNew: true,
|
|
123
|
+
},
|
|
124
|
+
),
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
// TODO These should still be tamed according to the permits before
|
|
128
|
+
// being made available.
|
|
129
|
+
for (const [name, value] of entries(perCompartmentGlobals)) {
|
|
130
|
+
defineProperty(globalObject, name, {
|
|
131
|
+
value,
|
|
132
|
+
writable: true,
|
|
133
|
+
enumerable: false,
|
|
134
|
+
configurable: true,
|
|
135
|
+
});
|
|
136
|
+
if (typeof value === 'function') {
|
|
137
|
+
markVirtualizedNativeFunction(value);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* setGlobalObjectEvaluators()
|
|
144
|
+
* Set the eval and the Function evaluator on the global object with given evalTaming policy.
|
|
145
|
+
*
|
|
146
|
+
* @param {object} globalObject
|
|
147
|
+
* @param {Function} evaluator
|
|
148
|
+
* @param {(object) => void} markVirtualizedNativeFunction
|
|
149
|
+
*/
|
|
150
|
+
export const setGlobalObjectEvaluators = (
|
|
151
|
+
globalObject,
|
|
152
|
+
evaluator,
|
|
153
|
+
markVirtualizedNativeFunction,
|
|
154
|
+
) => {
|
|
155
|
+
{
|
|
156
|
+
const f = freeze(makeEvalFunction(evaluator));
|
|
157
|
+
markVirtualizedNativeFunction(f);
|
|
158
|
+
defineProperty(globalObject, 'eval', {
|
|
159
|
+
value: f,
|
|
160
|
+
writable: true,
|
|
161
|
+
enumerable: false,
|
|
162
|
+
configurable: true,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
{
|
|
166
|
+
const f = freeze(makeFunctionConstructor(evaluator));
|
|
167
|
+
markVirtualizedNativeFunction(f);
|
|
168
|
+
defineProperty(globalObject, 'Function', {
|
|
169
|
+
value: f,
|
|
170
|
+
writable: true,
|
|
171
|
+
enumerable: false,
|
|
172
|
+
configurable: true,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
};
|