@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,79 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FERAL_FUNCTION,
|
|
3
|
+
arrayJoin,
|
|
4
|
+
arrayPop,
|
|
5
|
+
defineProperties,
|
|
6
|
+
getPrototypeOf,
|
|
7
|
+
} from './commons.js';
|
|
8
|
+
import { assert } from './error/assert.js';
|
|
9
|
+
|
|
10
|
+
const { Fail } = assert;
|
|
11
|
+
|
|
12
|
+
/*
|
|
13
|
+
* makeFunctionConstructor()
|
|
14
|
+
* A safe version of the native Function which relies on
|
|
15
|
+
* the safety of `safe-eval` for confinement, unless `no-eval`
|
|
16
|
+
* is specified (then a TypeError is thrown on use).
|
|
17
|
+
*/
|
|
18
|
+
export const makeFunctionConstructor = evaluator => {
|
|
19
|
+
// Define an unused parameter to ensure Function.length === 1
|
|
20
|
+
const newFunction = function Function(_body) {
|
|
21
|
+
// Sanitize all parameters at the entry point.
|
|
22
|
+
// eslint-disable-next-line prefer-rest-params
|
|
23
|
+
const bodyText = `${arrayPop(arguments) || ''}`;
|
|
24
|
+
// eslint-disable-next-line prefer-rest-params
|
|
25
|
+
const parameters = `${arrayJoin(arguments, ',')}`;
|
|
26
|
+
|
|
27
|
+
// Are parameters and bodyText valid code, or is someone
|
|
28
|
+
// attempting an injection attack? This will throw a SyntaxError if:
|
|
29
|
+
// - parameters doesn't parse as parameters
|
|
30
|
+
// - bodyText doesn't parse as a function body
|
|
31
|
+
// - either contain a call to super() or references a super property.
|
|
32
|
+
//
|
|
33
|
+
// It seems that XS may still be vulnerable to the attack explained at
|
|
34
|
+
// https://github.com/tc39/ecma262/pull/2374#issuecomment-813769710
|
|
35
|
+
// where `new Function('/*', '*/ ) {')` would incorrectly validate.
|
|
36
|
+
// Before we worried about this, we check the parameters and bodyText
|
|
37
|
+
// together in one call
|
|
38
|
+
// ```js
|
|
39
|
+
// new FERAL_FUNCTION(parameters, bodyTest);
|
|
40
|
+
// ```
|
|
41
|
+
// However, this check is vulnerable to that bug. Aside from that case,
|
|
42
|
+
// all engines do seem to validate the parameters, taken by themselves,
|
|
43
|
+
// correctly. And all engines do seem to validate the bodyText, taken
|
|
44
|
+
// by itself correctly. So with the following two checks, SES builds a
|
|
45
|
+
// correct safe `Function` constructor by composing two calls to an
|
|
46
|
+
// original unsafe `Function` constructor that may suffer from this bug
|
|
47
|
+
// but is otherwise correctly validating.
|
|
48
|
+
//
|
|
49
|
+
// eslint-disable-next-line no-new
|
|
50
|
+
new FERAL_FUNCTION(parameters, '');
|
|
51
|
+
// eslint-disable-next-line no-new
|
|
52
|
+
new FERAL_FUNCTION(bodyText);
|
|
53
|
+
|
|
54
|
+
// Safe to be combined. Defeat potential trailing comments.
|
|
55
|
+
// TODO: since we create an anonymous function, the 'this' value
|
|
56
|
+
// isn't bound to the global object as per specs, but set as undefined.
|
|
57
|
+
const src = `(function anonymous(${parameters}\n) {\n${bodyText}\n})`;
|
|
58
|
+
return evaluator(src);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
defineProperties(newFunction, {
|
|
62
|
+
// Ensure that any function created in any evaluator in a realm is an
|
|
63
|
+
// instance of Function in any evaluator of the same realm.
|
|
64
|
+
prototype: {
|
|
65
|
+
value: FERAL_FUNCTION.prototype,
|
|
66
|
+
writable: false,
|
|
67
|
+
enumerable: false,
|
|
68
|
+
configurable: false,
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// Assert identity of Function.__proto__ accross all compartments
|
|
73
|
+
getPrototypeOf(FERAL_FUNCTION) === FERAL_FUNCTION.prototype ||
|
|
74
|
+
Fail`Function prototype is the same accross compartments`;
|
|
75
|
+
getPrototypeOf(newFunction) === FERAL_FUNCTION.prototype ||
|
|
76
|
+
Fail`Function constructor prototype is the same across compartments`;
|
|
77
|
+
|
|
78
|
+
return newFunction;
|
|
79
|
+
};
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
// Adapted from SES/Caja - Copyright (C) 2011 Google Inc.
|
|
2
|
+
// Copyright (C) 2018 Agoric
|
|
3
|
+
|
|
4
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
// you may not use this file except in compliance with the License.
|
|
6
|
+
// You may obtain a copy of the License at
|
|
7
|
+
//
|
|
8
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
//
|
|
10
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
// See the License for the specific language governing permissions and
|
|
14
|
+
// limitations under the License.
|
|
15
|
+
|
|
16
|
+
// based upon:
|
|
17
|
+
// https://github.com/google/caja/blob/master/src/com/google/caja/ses/startSES.js
|
|
18
|
+
// https://github.com/google/caja/blob/master/src/com/google/caja/ses/repairES5.js
|
|
19
|
+
// then copied from proposal-frozen-realms deep-freeze.js
|
|
20
|
+
// then copied from SES/src/bundle/deepFreeze.js
|
|
21
|
+
|
|
22
|
+
// @ts-check
|
|
23
|
+
|
|
24
|
+
import {
|
|
25
|
+
Set,
|
|
26
|
+
String,
|
|
27
|
+
TypeError,
|
|
28
|
+
WeakSet,
|
|
29
|
+
globalThis,
|
|
30
|
+
apply,
|
|
31
|
+
arrayForEach,
|
|
32
|
+
defineProperty,
|
|
33
|
+
freeze,
|
|
34
|
+
getOwnPropertyDescriptor,
|
|
35
|
+
getOwnPropertyDescriptors,
|
|
36
|
+
getPrototypeOf,
|
|
37
|
+
isInteger,
|
|
38
|
+
isPrimitive,
|
|
39
|
+
hasOwn,
|
|
40
|
+
ownKeys,
|
|
41
|
+
preventExtensions,
|
|
42
|
+
setAdd,
|
|
43
|
+
setForEach,
|
|
44
|
+
setHas,
|
|
45
|
+
toStringTagSymbol,
|
|
46
|
+
typedArrayPrototype,
|
|
47
|
+
weaksetAdd,
|
|
48
|
+
weaksetHas,
|
|
49
|
+
FERAL_STACK_GETTER,
|
|
50
|
+
FERAL_STACK_SETTER,
|
|
51
|
+
isError,
|
|
52
|
+
} from './commons.js';
|
|
53
|
+
import { assert } from './error/assert.js';
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* @import {Harden} from '../types.js'
|
|
57
|
+
*/
|
|
58
|
+
|
|
59
|
+
// Obtain the string tag accessor of of TypedArray so we can indirectly use the
|
|
60
|
+
// TypedArray brand check it employs.
|
|
61
|
+
const typedArrayToStringTag = getOwnPropertyDescriptor(
|
|
62
|
+
typedArrayPrototype,
|
|
63
|
+
toStringTagSymbol,
|
|
64
|
+
);
|
|
65
|
+
assert(typedArrayToStringTag);
|
|
66
|
+
const getTypedArrayToStringTag = typedArrayToStringTag.get;
|
|
67
|
+
assert(getTypedArrayToStringTag);
|
|
68
|
+
|
|
69
|
+
// Exported for tests.
|
|
70
|
+
/**
|
|
71
|
+
* Duplicates packages/marshal/src/helpers/passStyle-helpers.js to avoid a dependency.
|
|
72
|
+
*
|
|
73
|
+
* @param {unknown} object
|
|
74
|
+
*/
|
|
75
|
+
export const isTypedArray = object => {
|
|
76
|
+
// The object must pass a brand check or toStringTag will return undefined.
|
|
77
|
+
const tag = apply(getTypedArrayToStringTag, object, []);
|
|
78
|
+
return tag !== undefined;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Tests if a property key is an integer-valued canonical numeric index.
|
|
83
|
+
* https://tc39.es/ecma262/#sec-canonicalnumericindexstring
|
|
84
|
+
*
|
|
85
|
+
* @param {string | symbol} propertyKey
|
|
86
|
+
*/
|
|
87
|
+
const isCanonicalIntegerIndexString = propertyKey => {
|
|
88
|
+
const n = +String(propertyKey);
|
|
89
|
+
return isInteger(n) && String(n) === propertyKey;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* @template T
|
|
94
|
+
* @param {ArrayLike<T>} array
|
|
95
|
+
*/
|
|
96
|
+
const freezeTypedArray = array => {
|
|
97
|
+
preventExtensions(array);
|
|
98
|
+
|
|
99
|
+
// Downgrade writable expandos to readonly, even if non-configurable.
|
|
100
|
+
// We get each descriptor individually rather than using
|
|
101
|
+
// getOwnPropertyDescriptors in order to fail safe when encountering
|
|
102
|
+
// an obscure GraalJS issue where getOwnPropertyDescriptor returns
|
|
103
|
+
// undefined for a property that does exist.
|
|
104
|
+
arrayForEach(ownKeys(array), (/** @type {string | symbol} */ name) => {
|
|
105
|
+
const desc = getOwnPropertyDescriptor(array, name);
|
|
106
|
+
assert(desc);
|
|
107
|
+
// TypedArrays are integer-indexed exotic objects, which define special
|
|
108
|
+
// treatment for property names in canonical numeric form:
|
|
109
|
+
// integers in range are permanently writable and non-configurable.
|
|
110
|
+
// https://tc39.es/ecma262/#sec-integer-indexed-exotic-objects
|
|
111
|
+
//
|
|
112
|
+
// This is analogous to the data of a hardened Map or Set,
|
|
113
|
+
// so we carve out this exceptional behavior but make all other
|
|
114
|
+
// properties non-configurable.
|
|
115
|
+
if (!isCanonicalIntegerIndexString(name)) {
|
|
116
|
+
defineProperty(array, name, {
|
|
117
|
+
...desc,
|
|
118
|
+
writable: false,
|
|
119
|
+
configurable: false,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Create a `harden` function.
|
|
127
|
+
*
|
|
128
|
+
* @returns {Harden}
|
|
129
|
+
*/
|
|
130
|
+
export const makeHardener = () => {
|
|
131
|
+
// Use a native hardener if possible.
|
|
132
|
+
if (typeof globalThis.harden === 'function') {
|
|
133
|
+
const safeHarden = globalThis.harden;
|
|
134
|
+
return safeHarden;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const hardened = new WeakSet();
|
|
138
|
+
|
|
139
|
+
const { harden } = {
|
|
140
|
+
/**
|
|
141
|
+
* @template T
|
|
142
|
+
* @param {T} root
|
|
143
|
+
* @returns {T}
|
|
144
|
+
*/
|
|
145
|
+
harden(root) {
|
|
146
|
+
const toFreeze = new Set();
|
|
147
|
+
|
|
148
|
+
// If val is something we should be freezing but aren't yet,
|
|
149
|
+
// add it to toFreeze.
|
|
150
|
+
/**
|
|
151
|
+
* @param {any} val
|
|
152
|
+
*/
|
|
153
|
+
function enqueue(val) {
|
|
154
|
+
if (isPrimitive(val)) {
|
|
155
|
+
// ignore primitives
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
const type = typeof val;
|
|
159
|
+
if (type !== 'object' && type !== 'function') {
|
|
160
|
+
// future proof: break until someone figures out what it should do
|
|
161
|
+
throw TypeError(`Unexpected typeof: ${type}`);
|
|
162
|
+
}
|
|
163
|
+
if (weaksetHas(hardened, val) || setHas(toFreeze, val)) {
|
|
164
|
+
// Ignore if this is an exit, or we've already visited it
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
// console.warn(`adding ${val} to toFreeze`, val);
|
|
168
|
+
setAdd(toFreeze, val);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* @param {any} obj
|
|
173
|
+
*/
|
|
174
|
+
const baseFreezeAndTraverse = obj => {
|
|
175
|
+
// Now freeze the object to ensure reactive
|
|
176
|
+
// objects such as proxies won't add properties
|
|
177
|
+
// during traversal, before they get frozen.
|
|
178
|
+
|
|
179
|
+
// Object are verified before being enqueued,
|
|
180
|
+
// therefore this is a valid candidate.
|
|
181
|
+
// Throws if this fails (strict mode).
|
|
182
|
+
// Also throws if the object is an ArrayBuffer or any TypedArray.
|
|
183
|
+
if (isTypedArray(obj)) {
|
|
184
|
+
freezeTypedArray(obj);
|
|
185
|
+
} else {
|
|
186
|
+
freeze(obj);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// we rely upon certain commitments of Object.freeze and proxies here
|
|
190
|
+
|
|
191
|
+
// get stable/immutable outbound links before a Proxy has a chance to do
|
|
192
|
+
// something sneaky.
|
|
193
|
+
const descs = getOwnPropertyDescriptors(obj);
|
|
194
|
+
const proto = getPrototypeOf(obj);
|
|
195
|
+
enqueue(proto);
|
|
196
|
+
|
|
197
|
+
arrayForEach(ownKeys(descs), (/** @type {string | symbol} */ name) => {
|
|
198
|
+
// The 'name' may be a symbol, and TypeScript doesn't like us to
|
|
199
|
+
// index arbitrary symbols on objects, so we pretend they're just
|
|
200
|
+
// strings.
|
|
201
|
+
const desc = descs[/** @type {string} */ (name)];
|
|
202
|
+
// getOwnPropertyDescriptors is guaranteed to return well-formed
|
|
203
|
+
// descriptors, but they still inherit from Object.prototype. If
|
|
204
|
+
// someone has poisoned Object.prototype to add 'value' or 'get'
|
|
205
|
+
// properties, then a simple 'if ("value" in desc)' or 'desc.value'
|
|
206
|
+
// test could be confused. We use hasOwnProperty to be sure about
|
|
207
|
+
// whether 'value' is present or not, which tells us for sure that
|
|
208
|
+
// this is a data property.
|
|
209
|
+
if (hasOwn(desc, 'value')) {
|
|
210
|
+
enqueue(desc.value);
|
|
211
|
+
} else {
|
|
212
|
+
enqueue(desc.get);
|
|
213
|
+
enqueue(desc.set);
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
const freezeAndTraverse =
|
|
219
|
+
FERAL_STACK_GETTER === undefined && FERAL_STACK_SETTER === undefined
|
|
220
|
+
? // On platforms without v8's error own stack accessor problem,
|
|
221
|
+
// don't pay for any extra overhead.
|
|
222
|
+
baseFreezeAndTraverse
|
|
223
|
+
: obj => {
|
|
224
|
+
if (isError(obj)) {
|
|
225
|
+
// Only pay the overhead if it first passes this cheap isError
|
|
226
|
+
// check. Otherwise, it will be unrepaired, but won't be judged
|
|
227
|
+
// to be a passable error anyway, so will not be unsafe.
|
|
228
|
+
const stackDesc = getOwnPropertyDescriptor(obj, 'stack');
|
|
229
|
+
if (
|
|
230
|
+
stackDesc &&
|
|
231
|
+
stackDesc.get === FERAL_STACK_GETTER &&
|
|
232
|
+
stackDesc.configurable
|
|
233
|
+
) {
|
|
234
|
+
// Can only repair if it is configurable. Otherwise, leave
|
|
235
|
+
// unrepaired, in which case it will not be judged passable,
|
|
236
|
+
// avoiding a safety problem.
|
|
237
|
+
defineProperty(obj, 'stack', {
|
|
238
|
+
// NOTE: Calls getter during harden, which seems dangerous.
|
|
239
|
+
// But we're only calling the problematic getter whose
|
|
240
|
+
// hazards we think we understand.
|
|
241
|
+
// @ts-expect-error TS should know FERAL_STACK_GETTER
|
|
242
|
+
// cannot be `undefined` here.
|
|
243
|
+
// See https://github.com/endojs/endo/pull/2232#discussion_r1575179471
|
|
244
|
+
value: apply(FERAL_STACK_GETTER, obj, []),
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
return baseFreezeAndTraverse(obj);
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
const dequeue = () => {
|
|
252
|
+
// New values added before forEach() has finished will be visited.
|
|
253
|
+
setForEach(toFreeze, freezeAndTraverse);
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
/** @param {any} value */
|
|
257
|
+
const markHardened = value => {
|
|
258
|
+
weaksetAdd(hardened, value);
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
const commit = () => {
|
|
262
|
+
setForEach(toFreeze, markHardened);
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
enqueue(root);
|
|
266
|
+
dequeue();
|
|
267
|
+
// console.warn("toFreeze set:", toFreeze);
|
|
268
|
+
commit();
|
|
269
|
+
|
|
270
|
+
return root;
|
|
271
|
+
},
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
return harden;
|
|
275
|
+
};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
// Portions adapted from V8 - Copyright 2016 the V8 project authors.
|
|
2
|
+
// https://github.com/v8/v8/blob/master/src/builtins/builtins-function.cc
|
|
3
|
+
|
|
4
|
+
import { apply, arrayFlatMap, freeze, identity } from './commons.js';
|
|
5
|
+
import { strictScopeTerminator } from './strict-scope-terminator.js';
|
|
6
|
+
import { createSloppyGlobalsScopeTerminator } from './sloppy-globals-scope-terminator.js';
|
|
7
|
+
import { makeEvalScopeKit } from './eval-scope.js';
|
|
8
|
+
import { applyTransforms, mandatoryTransforms } from './transforms.js';
|
|
9
|
+
import { makeEvaluate } from './make-evaluate.js';
|
|
10
|
+
import { assert } from './error/assert.js';
|
|
11
|
+
|
|
12
|
+
const { Fail } = assert;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* makeSafeEvaluator()
|
|
16
|
+
* Build the low-level operation used by all evaluators:
|
|
17
|
+
* eval(), Function(), Compartment.prototype.evaluate().
|
|
18
|
+
*
|
|
19
|
+
* @param {object} options
|
|
20
|
+
* @param {object} options.globalObject
|
|
21
|
+
* @param {object} [options.moduleLexicals]
|
|
22
|
+
* @param {Array<import('./lockdown.js').Transform>} [options.globalTransforms]
|
|
23
|
+
* @param {boolean} [options.sloppyGlobalsMode]
|
|
24
|
+
*/
|
|
25
|
+
export const makeSafeEvaluator = ({
|
|
26
|
+
globalObject,
|
|
27
|
+
moduleLexicals = {},
|
|
28
|
+
globalTransforms = [],
|
|
29
|
+
sloppyGlobalsMode = false,
|
|
30
|
+
}) => {
|
|
31
|
+
const scopeTerminator = sloppyGlobalsMode
|
|
32
|
+
? createSloppyGlobalsScopeTerminator(globalObject)
|
|
33
|
+
: strictScopeTerminator;
|
|
34
|
+
const evalScopeKit = makeEvalScopeKit();
|
|
35
|
+
const { evalScope } = evalScopeKit;
|
|
36
|
+
|
|
37
|
+
const evaluateContext = freeze({
|
|
38
|
+
evalScope,
|
|
39
|
+
moduleLexicals,
|
|
40
|
+
globalObject,
|
|
41
|
+
scopeTerminator,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// Defer creating the actual evaluator to first use.
|
|
45
|
+
// Creating a compartment should be possible in no-eval environments
|
|
46
|
+
// It also allows more global constants to be captured by the optimizer
|
|
47
|
+
let evaluate;
|
|
48
|
+
const provideEvaluate = () => {
|
|
49
|
+
if (!evaluate) {
|
|
50
|
+
evaluate = makeEvaluate(evaluateContext);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @param {string} source
|
|
56
|
+
* @param {object} [options]
|
|
57
|
+
* @param {Array<import('./lockdown.js').Transform>} [options.localTransforms]
|
|
58
|
+
*/
|
|
59
|
+
const safeEvaluate = (source, options) => {
|
|
60
|
+
const { localTransforms = [] } = options || {};
|
|
61
|
+
provideEvaluate();
|
|
62
|
+
|
|
63
|
+
// Execute the mandatory transforms last to ensure that any rewritten code
|
|
64
|
+
// meets those mandatory requirements.
|
|
65
|
+
source = applyTransforms(
|
|
66
|
+
source,
|
|
67
|
+
arrayFlatMap(
|
|
68
|
+
[localTransforms, globalTransforms, [mandatoryTransforms]],
|
|
69
|
+
identity,
|
|
70
|
+
),
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
let err;
|
|
74
|
+
try {
|
|
75
|
+
// Allow next reference to eval produce the unsafe FERAL_EVAL.
|
|
76
|
+
// eslint-disable-next-line @endo/no-polymorphic-call
|
|
77
|
+
evalScopeKit.allowNextEvalToBeUnsafe();
|
|
78
|
+
|
|
79
|
+
// Ensure that "this" resolves to the safe global.
|
|
80
|
+
return apply(evaluate, globalObject, [source]);
|
|
81
|
+
} catch (e) {
|
|
82
|
+
// stash the child-code error in hopes of debugging the internal failure
|
|
83
|
+
err = e;
|
|
84
|
+
throw e;
|
|
85
|
+
} finally {
|
|
86
|
+
const unsafeEvalWasStillExposed = 'eval' in evalScope;
|
|
87
|
+
delete evalScope.eval;
|
|
88
|
+
if (unsafeEvalWasStillExposed) {
|
|
89
|
+
// Barring a defect in the SES shim, the evalScope should allow the
|
|
90
|
+
// powerful, unsafe `eval` to be used by `evaluate` exactly once, as the
|
|
91
|
+
// very first name that it attempts to access from the lexical scope.
|
|
92
|
+
// A defect in the SES shim could throw an exception after we set
|
|
93
|
+
// `evalScope.eval` and before `evaluate` calls `eval` internally.
|
|
94
|
+
// If we get here, SES is very broken.
|
|
95
|
+
// This condition is one where this vat is now hopelessly confused, and
|
|
96
|
+
// the vat as a whole should be aborted.
|
|
97
|
+
// No further code should run.
|
|
98
|
+
// All immediately reachable state should be abandoned.
|
|
99
|
+
// However, that is not yet possible, so we at least prevent further
|
|
100
|
+
// variable resolution via the scopeHandler, and throw an error with
|
|
101
|
+
// diagnostic info including the thrown error if any from evaluating the
|
|
102
|
+
// source code.
|
|
103
|
+
evalScopeKit.revoked = { err };
|
|
104
|
+
// TODO A GOOD PLACE TO PANIC(), i.e., kill the vat incarnation.
|
|
105
|
+
// See https://github.com/Agoric/SES-shim/issues/490
|
|
106
|
+
Fail`handler did not reset allowNextEvalToBeUnsafe ${err}`;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
return { safeEvaluate };
|
|
112
|
+
};
|