@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,41 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
TypeError,
|
|
5
|
+
globalThis,
|
|
6
|
+
getOwnPropertyDescriptor,
|
|
7
|
+
defineProperty,
|
|
8
|
+
} from './commons.js';
|
|
9
|
+
|
|
10
|
+
export function tameDomains(domainTaming = 'safe') {
|
|
11
|
+
if (domainTaming === 'unsafe') {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Protect against the hazard presented by Node.js domains.
|
|
16
|
+
const globalProcess = globalThis.process || undefined;
|
|
17
|
+
if (typeof globalProcess === 'object') {
|
|
18
|
+
// Check whether domains were initialized.
|
|
19
|
+
const domainDescriptor = getOwnPropertyDescriptor(globalProcess, 'domain');
|
|
20
|
+
if (domainDescriptor !== undefined && domainDescriptor.get !== undefined) {
|
|
21
|
+
// The domain descriptor on Node.js initially has value: null, which
|
|
22
|
+
// becomes a get, set pair after domains initialize.
|
|
23
|
+
// See https://github.com/endojs/endo/blob/master/packages/ses/error-codes/SES_NO_DOMAINS.md
|
|
24
|
+
throw TypeError(
|
|
25
|
+
`SES failed to lockdown, Node.js domains have been initialized (SES_NO_DOMAINS)`,
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
// Prevent domains from initializing.
|
|
29
|
+
// This is clunky because the exception thrown from the domains package does
|
|
30
|
+
// not direct the user's gaze toward a knowledge base about the problem.
|
|
31
|
+
// The domain module merely throws an exception when it attempts to define
|
|
32
|
+
// the domain property of the process global during its initialization.
|
|
33
|
+
// We have no better recourse because Node.js uses defineProperty too.
|
|
34
|
+
defineProperty(globalProcess, 'domain', {
|
|
35
|
+
value: null,
|
|
36
|
+
configurable: false,
|
|
37
|
+
writable: false,
|
|
38
|
+
enumerable: false,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getOwnPropertyDescriptor,
|
|
3
|
+
apply,
|
|
4
|
+
defineProperty,
|
|
5
|
+
toStringTagSymbol,
|
|
6
|
+
} from './commons.js';
|
|
7
|
+
|
|
8
|
+
const throws = thunk => {
|
|
9
|
+
try {
|
|
10
|
+
thunk();
|
|
11
|
+
return false;
|
|
12
|
+
} catch (er) {
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Exported for convenience of unit testing. Harmless, but not expected
|
|
19
|
+
* to be useful by itself.
|
|
20
|
+
*
|
|
21
|
+
* @param {any} obj
|
|
22
|
+
* @param {string|symbol} prop
|
|
23
|
+
* @param {any} expectedValue
|
|
24
|
+
* @returns {boolean}
|
|
25
|
+
* Returns whether `tameFauxDataProperty` turned the property in question
|
|
26
|
+
* from an apparent faux data property into the actual data property it
|
|
27
|
+
* seemed to emulate.
|
|
28
|
+
* If this function returns `false`, then we hope no effects happened.
|
|
29
|
+
* However, sniffing out if an accessor property seems to be a faux data
|
|
30
|
+
* property requires invoking the getter and setter functions that might
|
|
31
|
+
* possibly have side effects.
|
|
32
|
+
* `tameFauxDataProperty` is not in a position to tell.
|
|
33
|
+
*/
|
|
34
|
+
export const tameFauxDataProperty = (obj, prop, expectedValue) => {
|
|
35
|
+
if (obj === undefined) {
|
|
36
|
+
// The object does not exist in this version of the platform
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
const desc = getOwnPropertyDescriptor(obj, prop);
|
|
40
|
+
if (!desc || 'value' in desc) {
|
|
41
|
+
// The property either doesn't exist, or is already an actual data property.
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
const { get, set } = desc;
|
|
45
|
+
if (typeof get !== 'function' || typeof set !== 'function') {
|
|
46
|
+
// A faux data property has both a getter and a setter
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
if (get() !== expectedValue) {
|
|
50
|
+
// The getter called by itself should produce the expectedValue
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
if (apply(get, obj, []) !== expectedValue) {
|
|
54
|
+
// The getter called with `this === obj` should also return the
|
|
55
|
+
// expectedValue.
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
const testValue = 'Seems to be a setter';
|
|
59
|
+
const subject1 = { __proto__: null };
|
|
60
|
+
apply(set, subject1, [testValue]);
|
|
61
|
+
if (subject1[prop] !== testValue) {
|
|
62
|
+
// The setter called with an unrelated object as `this` should
|
|
63
|
+
// set the property on the object.
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
const subject2 = { __proto__: obj };
|
|
67
|
+
apply(set, subject2, [testValue]);
|
|
68
|
+
if (subject2[prop] !== testValue) {
|
|
69
|
+
// The setter called on an object that inherits from `obj` should
|
|
70
|
+
// override the property from `obj` as if by assignment.
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
if (!throws(() => apply(set, obj, [expectedValue]))) {
|
|
74
|
+
// The setter called with `this === obj` should throw without having
|
|
75
|
+
// caused any effect.
|
|
76
|
+
// This is the test that has the greatest danger of leaving behind some
|
|
77
|
+
// persistent side effect. The most obvious one is to emulate a
|
|
78
|
+
// successful assignment to the property. That's why this test
|
|
79
|
+
// uses `expectedValue`, so that case is likely not to actually
|
|
80
|
+
// change anything.
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
if ('originalValue' in get) {
|
|
84
|
+
// The ses-shim uniquely, as far as we know, puts an `originalValue`
|
|
85
|
+
// property on the getter, so that reflect property tranversal algorithms,
|
|
86
|
+
// like `harden`, will traverse into the enulated value without
|
|
87
|
+
// calling the getter. That does not happen until `permits-intrinsics.js`
|
|
88
|
+
// which is much later. So if we see one this early, we should
|
|
89
|
+
// not assume we understand what's going on.
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// We assume that this code runs before any untrusted code runs, so
|
|
94
|
+
// we do not need to worry about the above conditions passing because of
|
|
95
|
+
// malicious intent. In fact, it runs even before vetted shims are supposed
|
|
96
|
+
// to run, between repair and hardening. Given that, after all these tests
|
|
97
|
+
// pass, we have adequately validated that the property in question is
|
|
98
|
+
// an accessor function whose purpose is suppressing the override mistake,
|
|
99
|
+
// i.e., enabling a non-writable property to be overridden by assignment.
|
|
100
|
+
// In that case, here we *temporarily* turn it into the data property
|
|
101
|
+
// it seems to emulate, but writable so that it does not trigger the
|
|
102
|
+
// override mistake while in this temporary state.
|
|
103
|
+
|
|
104
|
+
// For those properties that are also listed in `enablements.js`,
|
|
105
|
+
// that phase will re-enable override for these properties, but
|
|
106
|
+
// via accessor functions that SES controls, so we know what they are
|
|
107
|
+
// doing. In addition, the getter functions installed by
|
|
108
|
+
// `enable-property-overrides.js` have an `originalValue` field
|
|
109
|
+
// enabling meta-traversal code like harden to visit the original value
|
|
110
|
+
// without calling the getter.
|
|
111
|
+
|
|
112
|
+
if (desc.configurable === false) {
|
|
113
|
+
// Even though it seems to be a faux data property, we're unable to fix it.
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Many of the `return false;` cases above plausibly should be turned into
|
|
118
|
+
// errors, or an least generate warnings. However, for those, the checks
|
|
119
|
+
// following this phase are likely to signal an error anyway.
|
|
120
|
+
|
|
121
|
+
// At this point, we have passed all our sniff checks for validating that
|
|
122
|
+
// it seems to be a faux data property with the expected value. Turn
|
|
123
|
+
// it into the actual data property it emulates, but writable so there is
|
|
124
|
+
// not yet an override mistake problem.
|
|
125
|
+
|
|
126
|
+
defineProperty(obj, prop, {
|
|
127
|
+
value: expectedValue,
|
|
128
|
+
writable: true,
|
|
129
|
+
enumerable: desc.enumerable,
|
|
130
|
+
configurable: true,
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
return true;
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* In JavaScript, the so-called "override mistake" is the inability to
|
|
138
|
+
* override an inherited non-writable data property by assignment. A common
|
|
139
|
+
* workaround is to instead define an accessor property that acts like
|
|
140
|
+
* a non-writable data property, except that it allows an object that
|
|
141
|
+
* inherits this property to override it by assignment. Let's call
|
|
142
|
+
* an access property that acts this way a "faux data property". In this
|
|
143
|
+
* ses-shim, `enable-property-overrides.js` makes the properties listed in
|
|
144
|
+
* `enablements.js` into faux data properties.
|
|
145
|
+
*
|
|
146
|
+
* But the ses-shim is not alone in use of this trick. Starting with the
|
|
147
|
+
* [Iterator Helpers proposal](https://github.com/tc39/proposal-iterator-helpers),
|
|
148
|
+
* some properties are defined as (what we call) faux data properties.
|
|
149
|
+
* Some of these are new properties (`Interator.prototype.constructor`) and
|
|
150
|
+
* some are old data properties converted to accessor properties
|
|
151
|
+
* (`Iterator.prototype[String.toStringTag]`). So the ses-shim needs to be
|
|
152
|
+
* prepared for some enumerated set of properties to already be faux data
|
|
153
|
+
* properties in the platform prior to our initialization.
|
|
154
|
+
*
|
|
155
|
+
* For these possible faux data properties, it is important that
|
|
156
|
+
* `permits.js` describe each as a data property, so that it can further
|
|
157
|
+
* constrain the apparent value (that allegedly would be returned by the
|
|
158
|
+
* getter) according to its own permits.
|
|
159
|
+
*
|
|
160
|
+
* However, at the time of this writing, the precise behavior specified
|
|
161
|
+
* by the iterator-helpers proposal for these faux data properties is
|
|
162
|
+
* novel. We should not be too confident that all further such platform
|
|
163
|
+
* additions do what we would now expect. So, for each of these possible
|
|
164
|
+
* faux data properties, we do some sniffing to see if it behaves as we
|
|
165
|
+
* currently expect a faux data property to act. If not, then
|
|
166
|
+
* `tameFauxDataProperties` tries not to modify it, leaving it to later
|
|
167
|
+
* checks, especially `permits-intrinsics.js`, to error when it sees an
|
|
168
|
+
* unexpected accessor.
|
|
169
|
+
*
|
|
170
|
+
* If one of these enumerated accessor properties does seem to be
|
|
171
|
+
* a faithful faux data property, then `tameFauxDataProperties` itself
|
|
172
|
+
* *tempoarily* turns it into the actual data property that it seems to emulate.
|
|
173
|
+
* This data property starts as writable, so that in this state it will
|
|
174
|
+
* not trigger the override mistake, i.e., assignment to an object inheriting
|
|
175
|
+
* this property is allowed to succeed at overriding this property.
|
|
176
|
+
*
|
|
177
|
+
* For those properties that should be a faux data property rather than an
|
|
178
|
+
* actual one, such as those from the iterator-helpers proposal,
|
|
179
|
+
* they should be listed as such in `enablements.js`, so
|
|
180
|
+
* `enable-property-overrides.js` will turn it back into a faux data property.
|
|
181
|
+
* But one controlled by the ses-shim, whose behavior we understand.
|
|
182
|
+
*
|
|
183
|
+
* `tameFauxDataProperties`, which turns these into actual data properties,
|
|
184
|
+
* happens during the `repairIntrinsics` phase
|
|
185
|
+
* of `lockdown`, before even vetted shim are supposed to run.
|
|
186
|
+
* `enable-property-overrides.js` runs after vetted shims, turning the
|
|
187
|
+
* appropriate ones back into faux data properties. Thus vetted shims
|
|
188
|
+
* can observe the possibly non-conforming state where these are temporarily
|
|
189
|
+
* actual data properties, rather than faux data properties.
|
|
190
|
+
*
|
|
191
|
+
* Coordinate the property enumeration here
|
|
192
|
+
* with `enablements.js`, so the appropriate properties are
|
|
193
|
+
* turned back to faux data properties.
|
|
194
|
+
*
|
|
195
|
+
* @param {Record<any,any>} intrinsics
|
|
196
|
+
*/
|
|
197
|
+
export const tameFauxDataProperties = intrinsics => {
|
|
198
|
+
// https://github.com/tc39/proposal-iterator-helpers
|
|
199
|
+
tameFauxDataProperty(
|
|
200
|
+
intrinsics['%IteratorPrototype%'],
|
|
201
|
+
'constructor',
|
|
202
|
+
intrinsics.Iterator,
|
|
203
|
+
);
|
|
204
|
+
// https://github.com/tc39/proposal-iterator-helpers
|
|
205
|
+
tameFauxDataProperty(
|
|
206
|
+
intrinsics['%IteratorPrototype%'],
|
|
207
|
+
toStringTagSymbol,
|
|
208
|
+
'Iterator',
|
|
209
|
+
);
|
|
210
|
+
};
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FERAL_FUNCTION,
|
|
3
|
+
SyntaxError,
|
|
4
|
+
TypeError,
|
|
5
|
+
defineProperties,
|
|
6
|
+
getPrototypeOf,
|
|
7
|
+
setPrototypeOf,
|
|
8
|
+
freeze,
|
|
9
|
+
AsyncGeneratorFunctionInstance,
|
|
10
|
+
} from './commons.js';
|
|
11
|
+
|
|
12
|
+
// This module replaces the original `Function` constructor, and the original
|
|
13
|
+
// `%GeneratorFunction%`, `%AsyncFunction%` and `%AsyncGeneratorFunction%`,
|
|
14
|
+
// with safe replacements that throw if invoked.
|
|
15
|
+
//
|
|
16
|
+
// These are all reachable via syntax, so it isn't sufficient to just
|
|
17
|
+
// replace global properties with safe versions. Our main goal is to prevent
|
|
18
|
+
// access to the `Function` constructor through these starting points.
|
|
19
|
+
//
|
|
20
|
+
// After modules block is done, the originals must no longer be reachable,
|
|
21
|
+
// unless a copy has been made, and functions can only be created by syntax
|
|
22
|
+
// (using eval) or by invoking a previously saved reference to the originals.
|
|
23
|
+
//
|
|
24
|
+
// Typically, this module will not be used directly, but via the
|
|
25
|
+
// [lockdown - shim] which handles all necessary repairs and taming in SES.
|
|
26
|
+
//
|
|
27
|
+
// Relation to ECMA specifications
|
|
28
|
+
//
|
|
29
|
+
// The taming of constructors really wants to be part of the standard, because
|
|
30
|
+
// new constructors may be added in the future, reachable from syntax, and this
|
|
31
|
+
// list must be updated to match.
|
|
32
|
+
//
|
|
33
|
+
// In addition, the standard needs to define four new intrinsics for the safe
|
|
34
|
+
// replacement functions. See [./permits-intrinsics.js].
|
|
35
|
+
//
|
|
36
|
+
// Adapted from SES/Caja
|
|
37
|
+
// Copyright (C) 2011 Google Inc.
|
|
38
|
+
// https://github.com/google/caja/blob/master/src/com/google/caja/ses/startSES.js
|
|
39
|
+
// https://github.com/google/caja/blob/master/src/com/google/caja/ses/repairES5.js
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* tameFunctionConstructors()
|
|
43
|
+
* This block replaces the original Function constructor, and the original
|
|
44
|
+
* %GeneratorFunction% %AsyncFunction% and %AsyncGeneratorFunction%, with
|
|
45
|
+
* safe replacements that throw if invoked.
|
|
46
|
+
*/
|
|
47
|
+
export default function tameFunctionConstructors() {
|
|
48
|
+
try {
|
|
49
|
+
// Verify that the method is not callable.
|
|
50
|
+
// eslint-disable-next-line @endo/no-polymorphic-call
|
|
51
|
+
FERAL_FUNCTION.prototype.constructor('return 1');
|
|
52
|
+
} catch (ignore) {
|
|
53
|
+
// Throws, no need to patch.
|
|
54
|
+
return freeze({});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const newIntrinsics = {};
|
|
58
|
+
|
|
59
|
+
/*
|
|
60
|
+
* The process to repair constructors:
|
|
61
|
+
* 1. Create an instance of the function by evaluating syntax
|
|
62
|
+
* 2. Obtain the prototype from the instance
|
|
63
|
+
* 3. Create a substitute tamed constructor
|
|
64
|
+
* 4. Replace the original constructor with the tamed constructor
|
|
65
|
+
* 5. Replace tamed constructor prototype property with the original one
|
|
66
|
+
* 6. Replace its [[Prototype]] slot with the tamed constructor of Function
|
|
67
|
+
*/
|
|
68
|
+
function repairFunction(name, intrinsicName, declaration) {
|
|
69
|
+
let FunctionInstance;
|
|
70
|
+
try {
|
|
71
|
+
// eslint-disable-next-line no-eval, no-restricted-globals
|
|
72
|
+
FunctionInstance = (0, eval)(declaration);
|
|
73
|
+
} catch (e) {
|
|
74
|
+
if (e instanceof SyntaxError) {
|
|
75
|
+
// Prevent failure on platforms where async and/or generators
|
|
76
|
+
// are not supported.
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
// Re-throw
|
|
80
|
+
throw e;
|
|
81
|
+
}
|
|
82
|
+
const FunctionPrototype = getPrototypeOf(FunctionInstance);
|
|
83
|
+
|
|
84
|
+
// Prevents the evaluation of source when calling constructor on the
|
|
85
|
+
// prototype of functions.
|
|
86
|
+
// eslint-disable-next-line func-names
|
|
87
|
+
const InertConstructor = function () {
|
|
88
|
+
throw TypeError(
|
|
89
|
+
'Function.prototype.constructor is not a valid constructor.',
|
|
90
|
+
);
|
|
91
|
+
};
|
|
92
|
+
defineProperties(InertConstructor, {
|
|
93
|
+
prototype: { value: FunctionPrototype },
|
|
94
|
+
name: {
|
|
95
|
+
value: name,
|
|
96
|
+
writable: false,
|
|
97
|
+
enumerable: false,
|
|
98
|
+
configurable: true,
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
defineProperties(FunctionPrototype, {
|
|
103
|
+
constructor: { value: InertConstructor },
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// Reconstructs the inheritance among the new tamed constructors
|
|
107
|
+
// to mirror the original specified in normal JS.
|
|
108
|
+
if (InertConstructor !== FERAL_FUNCTION.prototype.constructor) {
|
|
109
|
+
setPrototypeOf(InertConstructor, FERAL_FUNCTION.prototype.constructor);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
newIntrinsics[intrinsicName] = InertConstructor;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Here, the order of operation is important: Function needs to be repaired
|
|
116
|
+
// first since the other repaired constructors need to inherit from the
|
|
117
|
+
// tamed Function function constructor.
|
|
118
|
+
|
|
119
|
+
repairFunction('Function', '%InertFunction%', '(function(){})');
|
|
120
|
+
repairFunction(
|
|
121
|
+
'GeneratorFunction',
|
|
122
|
+
'%InertGeneratorFunction%',
|
|
123
|
+
'(function*(){})',
|
|
124
|
+
);
|
|
125
|
+
repairFunction(
|
|
126
|
+
'AsyncFunction',
|
|
127
|
+
'%InertAsyncFunction%',
|
|
128
|
+
'(async function(){})',
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
if (AsyncGeneratorFunctionInstance !== undefined) {
|
|
132
|
+
repairFunction(
|
|
133
|
+
'AsyncGeneratorFunction',
|
|
134
|
+
'%InertAsyncGeneratorFunction%',
|
|
135
|
+
'(async function*(){})',
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return newIntrinsics;
|
|
140
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import {
|
|
2
|
+
WeakSet,
|
|
3
|
+
defineProperty,
|
|
4
|
+
freeze,
|
|
5
|
+
functionPrototype,
|
|
6
|
+
functionToString,
|
|
7
|
+
stringEndsWith,
|
|
8
|
+
weaksetAdd,
|
|
9
|
+
weaksetHas,
|
|
10
|
+
} from './commons.js';
|
|
11
|
+
|
|
12
|
+
const nativeSuffix = ') { [native code] }';
|
|
13
|
+
|
|
14
|
+
// Note: Top level mutable state. Does not make anything worse, since the
|
|
15
|
+
// patching of `Function.prototype.toString` is also globally stateful. We
|
|
16
|
+
// use this top level state so that multiple calls to `tameFunctionToString` are
|
|
17
|
+
// idempotent, rather than creating redundant indirections.
|
|
18
|
+
let markVirtualizedNativeFunction;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Replace `Function.prototype.toString` with one that recognizes
|
|
22
|
+
* shimmed functions as honorary native functions.
|
|
23
|
+
*/
|
|
24
|
+
export const tameFunctionToString = () => {
|
|
25
|
+
if (markVirtualizedNativeFunction === undefined) {
|
|
26
|
+
const virtualizedNativeFunctions = new WeakSet();
|
|
27
|
+
|
|
28
|
+
const tamingMethods = {
|
|
29
|
+
toString() {
|
|
30
|
+
const str = functionToString(this);
|
|
31
|
+
if (
|
|
32
|
+
stringEndsWith(str, nativeSuffix) ||
|
|
33
|
+
!weaksetHas(virtualizedNativeFunctions, this)
|
|
34
|
+
) {
|
|
35
|
+
return str;
|
|
36
|
+
}
|
|
37
|
+
return `function ${this.name}() { [native code] }`;
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
defineProperty(functionPrototype, 'toString', {
|
|
42
|
+
value: tamingMethods.toString,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
markVirtualizedNativeFunction = freeze(func =>
|
|
46
|
+
weaksetAdd(virtualizedNativeFunctions, func),
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
return markVirtualizedNativeFunction;
|
|
50
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/* eslint-disable no-restricted-globals */
|
|
2
|
+
import { freeze } from './commons.js';
|
|
3
|
+
|
|
4
|
+
/** @import {Harden} from '../types.js'; */
|
|
5
|
+
|
|
6
|
+
/** @type {(safeHarden: Harden, hardenTaming: 'safe' | 'unsafe') => Harden} */
|
|
7
|
+
export const tameHarden = (safeHarden, hardenTaming) => {
|
|
8
|
+
if (hardenTaming === 'safe') {
|
|
9
|
+
return safeHarden;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// In on the joke
|
|
13
|
+
Object.isExtensible = () => false;
|
|
14
|
+
Object.isFrozen = () => true;
|
|
15
|
+
Object.isSealed = () => true;
|
|
16
|
+
Reflect.isExtensible = () => false;
|
|
17
|
+
|
|
18
|
+
// @ts-expect-error secret property
|
|
19
|
+
if (safeHarden.isFake) {
|
|
20
|
+
// The "safe" hardener is already a fake hardener.
|
|
21
|
+
// Just use it.
|
|
22
|
+
return safeHarden;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const fakeHarden = arg => arg;
|
|
26
|
+
fakeHarden.isFake = true;
|
|
27
|
+
return freeze(fakeHarden);
|
|
28
|
+
};
|
|
29
|
+
freeze(tameHarden);
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Number,
|
|
3
|
+
String,
|
|
4
|
+
TypeError,
|
|
5
|
+
defineProperty,
|
|
6
|
+
getOwnPropertyNames,
|
|
7
|
+
isPrimitive,
|
|
8
|
+
regexpExec,
|
|
9
|
+
} from './commons.js';
|
|
10
|
+
import { assert } from './error/assert.js';
|
|
11
|
+
|
|
12
|
+
const { Fail, quote: q } = assert;
|
|
13
|
+
|
|
14
|
+
const localePattern = /^(\w*[a-z])Locale([A-Z]\w*)$/;
|
|
15
|
+
|
|
16
|
+
// Use concise methods to obtain named functions without constructor
|
|
17
|
+
// behavior or `.prototype` property.
|
|
18
|
+
const tamedMethods = {
|
|
19
|
+
// See https://tc39.es/ecma262/#sec-string.prototype.localecompare
|
|
20
|
+
localeCompare(arg) {
|
|
21
|
+
if (this === null || this === undefined) {
|
|
22
|
+
throw TypeError(
|
|
23
|
+
'Cannot localeCompare with null or undefined "this" value',
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
const s = `${this}`;
|
|
27
|
+
const that = `${arg}`;
|
|
28
|
+
if (s < that) {
|
|
29
|
+
return -1;
|
|
30
|
+
}
|
|
31
|
+
if (s > that) {
|
|
32
|
+
return 1;
|
|
33
|
+
}
|
|
34
|
+
s === that || Fail`expected ${q(s)} and ${q(that)} to compare`;
|
|
35
|
+
return 0;
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
toString() {
|
|
39
|
+
return `${this}`;
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const nonLocaleCompare = tamedMethods.localeCompare;
|
|
44
|
+
const numberToString = tamedMethods.toString;
|
|
45
|
+
|
|
46
|
+
export default function tameLocaleMethods(intrinsics, localeTaming = 'safe') {
|
|
47
|
+
if (localeTaming === 'unsafe') {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
defineProperty(String.prototype, 'localeCompare', {
|
|
52
|
+
value: nonLocaleCompare,
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
for (const intrinsicName of getOwnPropertyNames(intrinsics)) {
|
|
56
|
+
const intrinsic = intrinsics[intrinsicName];
|
|
57
|
+
if (!isPrimitive(intrinsic)) {
|
|
58
|
+
for (const methodName of getOwnPropertyNames(intrinsic)) {
|
|
59
|
+
const match = regexpExec(localePattern, methodName);
|
|
60
|
+
if (match) {
|
|
61
|
+
typeof intrinsic[methodName] === 'function' ||
|
|
62
|
+
Fail`expected ${q(methodName)} to be a function`;
|
|
63
|
+
const nonLocaleMethodName = `${match[1]}${match[2]}`;
|
|
64
|
+
const method = intrinsic[nonLocaleMethodName];
|
|
65
|
+
typeof method === 'function' ||
|
|
66
|
+
Fail`function ${q(nonLocaleMethodName)} not found`;
|
|
67
|
+
defineProperty(intrinsic, methodName, { value: method });
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Numbers are special because toString accepts a radix instead of ignoring
|
|
74
|
+
// all of the arguments that we would otherwise forward.
|
|
75
|
+
defineProperty(Number.prototype, 'toLocaleString', {
|
|
76
|
+
value: numberToString,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Math,
|
|
3
|
+
TypeError,
|
|
4
|
+
create,
|
|
5
|
+
getOwnPropertyDescriptors,
|
|
6
|
+
objectPrototype,
|
|
7
|
+
} from './commons.js';
|
|
8
|
+
|
|
9
|
+
export default function tameMathObject() {
|
|
10
|
+
const originalMath = Math;
|
|
11
|
+
const initialMath = originalMath; // to follow the naming pattern
|
|
12
|
+
|
|
13
|
+
const { random: _, ...otherDescriptors } =
|
|
14
|
+
getOwnPropertyDescriptors(originalMath);
|
|
15
|
+
|
|
16
|
+
// Use concise methods to obtain named functions without constructors.
|
|
17
|
+
const tamedMethods = {
|
|
18
|
+
/**
|
|
19
|
+
* `%SharedMath%.random()` throws a TypeError starting with "secure mode".
|
|
20
|
+
* See https://github.com/endojs/endo/issues/910#issuecomment-1581855420
|
|
21
|
+
*/
|
|
22
|
+
random() {
|
|
23
|
+
throw TypeError('secure mode %SharedMath%.random() throws');
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const sharedMath = create(objectPrototype, {
|
|
28
|
+
...otherDescriptors,
|
|
29
|
+
random: {
|
|
30
|
+
value: tamedMethods.random,
|
|
31
|
+
writable: true,
|
|
32
|
+
enumerable: false,
|
|
33
|
+
configurable: true,
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
'%InitialMath%': initialMath,
|
|
39
|
+
'%SharedMath%': sharedMath,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import {
|
|
2
|
+
functionPrototype,
|
|
3
|
+
getPrototypeOf,
|
|
4
|
+
globalThis,
|
|
5
|
+
objectPrototype,
|
|
6
|
+
setPrototypeOf,
|
|
7
|
+
} from './commons.js';
|
|
8
|
+
|
|
9
|
+
export const tameModuleSource = () => {
|
|
10
|
+
const newIntrinsics = {};
|
|
11
|
+
|
|
12
|
+
const ModuleSource = globalThis.ModuleSource;
|
|
13
|
+
if (ModuleSource !== undefined) {
|
|
14
|
+
newIntrinsics.ModuleSource = ModuleSource;
|
|
15
|
+
|
|
16
|
+
// We introduce ModuleSource.[[Proto]] === AbstractModuleSource
|
|
17
|
+
// and ModuleSource.prototype.[[Proto]] === AbstractModuleSource.prototype
|
|
18
|
+
// if that layer is absent because the permitting system can more
|
|
19
|
+
// gracefully tolerate the absence of an expected prototype than the
|
|
20
|
+
// presence of an unexpected prototype,.
|
|
21
|
+
function AbstractModuleSource() {
|
|
22
|
+
// no-op safe to super()
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const ModuleSourceProto = getPrototypeOf(ModuleSource);
|
|
26
|
+
if (ModuleSourceProto === functionPrototype) {
|
|
27
|
+
setPrototypeOf(ModuleSource, AbstractModuleSource);
|
|
28
|
+
newIntrinsics['%AbstractModuleSource%'] = AbstractModuleSource;
|
|
29
|
+
newIntrinsics['%AbstractModuleSourcePrototype%'] =
|
|
30
|
+
AbstractModuleSource.prototype;
|
|
31
|
+
} else {
|
|
32
|
+
newIntrinsics['%AbstractModuleSource%'] = ModuleSourceProto;
|
|
33
|
+
newIntrinsics['%AbstractModuleSourcePrototype%'] =
|
|
34
|
+
ModuleSourceProto.prototype;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const ModuleSourcePrototype = ModuleSource.prototype;
|
|
38
|
+
if (ModuleSourcePrototype !== undefined) {
|
|
39
|
+
newIntrinsics['%ModuleSourcePrototype%'] = ModuleSourcePrototype;
|
|
40
|
+
|
|
41
|
+
// ModuleSource.prototype.__proto__ should be the
|
|
42
|
+
// AbstractModuleSource.prototype.
|
|
43
|
+
const ModuleSourcePrototypeProto = getPrototypeOf(ModuleSourcePrototype);
|
|
44
|
+
if (ModuleSourcePrototypeProto === objectPrototype) {
|
|
45
|
+
setPrototypeOf(ModuleSource.prototype, AbstractModuleSource.prototype);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return newIntrinsics;
|
|
51
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import {
|
|
2
|
+
defineProperty,
|
|
3
|
+
iteratorPrototype,
|
|
4
|
+
iteratorSymbol,
|
|
5
|
+
hasOwn,
|
|
6
|
+
} from './commons.js';
|
|
7
|
+
|
|
8
|
+
export const tameRegeneratorRuntime = () => {
|
|
9
|
+
const iter = iteratorPrototype[iteratorSymbol];
|
|
10
|
+
defineProperty(iteratorPrototype, iteratorSymbol, {
|
|
11
|
+
configurable: true,
|
|
12
|
+
get() {
|
|
13
|
+
return iter;
|
|
14
|
+
},
|
|
15
|
+
set(value) {
|
|
16
|
+
// ignore the assignment on IteratorPrototype
|
|
17
|
+
if (this === iteratorPrototype) return;
|
|
18
|
+
if (hasOwn(this, iteratorSymbol)) {
|
|
19
|
+
this[iteratorSymbol] = value;
|
|
20
|
+
}
|
|
21
|
+
defineProperty(this, iteratorSymbol, {
|
|
22
|
+
value,
|
|
23
|
+
writable: true,
|
|
24
|
+
enumerable: true,
|
|
25
|
+
configurable: true,
|
|
26
|
+
});
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
};
|