@poe-platform/safe-js 0.1.169 → 0.1.171
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/dist/safe-js/chunks/{chunk-MWL55BSP.js → chunk-OUFC6W7G.js} +2 -2
- package/dist/safe-js/chunks/{chunk-6UY4Z7WY.js → chunk-XKCTB5FR.js} +351 -158
- package/dist/safe-js/chunks/chunk-XKCTB5FR.js.map +7 -0
- package/dist/safe-js/cli.js +2 -2
- package/dist/safe-js/core.js +1 -1
- package/dist/safe-js/index.js +2 -2
- package/dist/safe-js/interp/regexp-properties.d.ts +3 -0
- package/dist/safe-js/interp/values.d.ts +1 -0
- package/dist/safe-js/snapshot/regexp-properties.d.ts +18 -0
- package/dist/safe-js/snapshot/replay-data.d.ts +3 -2
- package/package.json +2 -2
- package/dist/safe-js/chunks/chunk-6UY4Z7WY.js.map +0 -7
- /package/dist/safe-js/chunks/{chunk-MWL55BSP.js.map → chunk-OUFC6W7G.js.map} +0 -0
|
@@ -6165,87 +6165,6 @@ function matchingOpeningPunctuator(value) {
|
|
|
6165
6165
|
return "{";
|
|
6166
6166
|
}
|
|
6167
6167
|
|
|
6168
|
-
// packages/safe-js/src/extensions.ts
|
|
6169
|
-
import { types } from "node:util";
|
|
6170
|
-
var definitions = /* @__PURE__ */ new WeakMap();
|
|
6171
|
-
function readDataRecord(value, label) {
|
|
6172
|
-
if (typeof value !== "object" || value === null || types.isProxy(value)) {
|
|
6173
|
-
throw new TypeError(`${label} must be a plain data record.`);
|
|
6174
|
-
}
|
|
6175
|
-
const prototype = Object.getPrototypeOf(value);
|
|
6176
|
-
if (prototype !== null && prototype !== Object.prototype) {
|
|
6177
|
-
throw new TypeError(`${label} must be a plain data record.`);
|
|
6178
|
-
}
|
|
6179
|
-
const keys = Reflect.ownKeys(value);
|
|
6180
|
-
if (keys.length > 4096) throw new RangeError(`${label} has too many fields.`);
|
|
6181
|
-
const result = /* @__PURE__ */ Object.create(null);
|
|
6182
|
-
for (const key of keys) {
|
|
6183
|
-
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
6184
|
-
if (typeof key !== "string" || !("value" in descriptor)) {
|
|
6185
|
-
throw new TypeError(`${label} requires string-keyed data properties, not accessors.`);
|
|
6186
|
-
}
|
|
6187
|
-
result[key] = descriptor.value;
|
|
6188
|
-
}
|
|
6189
|
-
return result;
|
|
6190
|
-
}
|
|
6191
|
-
function readStringList(value, label) {
|
|
6192
|
-
if (!Array.isArray(value) || types.isProxy(value) || value.length > 4096) {
|
|
6193
|
-
throw new TypeError(`${label} must be a bounded string array.`);
|
|
6194
|
-
}
|
|
6195
|
-
const result = [];
|
|
6196
|
-
for (let index = 0; index < value.length; index++) {
|
|
6197
|
-
const descriptor = Object.getOwnPropertyDescriptor(value, String(index));
|
|
6198
|
-
if (descriptor === void 0 || !("value" in descriptor) || typeof descriptor.value !== "string" || descriptor.value.length === 0) {
|
|
6199
|
-
throw new TypeError(`${label} requires nonempty string data properties.`);
|
|
6200
|
-
}
|
|
6201
|
-
if (result.includes(descriptor.value))
|
|
6202
|
-
throw new TypeError(`${label} contains a duplicate name.`);
|
|
6203
|
-
result.push(descriptor.value);
|
|
6204
|
-
}
|
|
6205
|
-
if (Reflect.ownKeys(value).length !== result.length + 1)
|
|
6206
|
-
throw new TypeError(`${label} has unexpected fields.`);
|
|
6207
|
-
return Object.freeze(result);
|
|
6208
|
-
}
|
|
6209
|
-
function defineExtension(definition) {
|
|
6210
|
-
const input = readDataRecord(definition, "Extension definition");
|
|
6211
|
-
if (Object.keys(input).some((key) => key !== "manifest" && key !== "setup"))
|
|
6212
|
-
throw new TypeError("Unknown extension definition field.");
|
|
6213
|
-
if (typeof input.setup !== "function") throw new TypeError("Extension setup must be a function.");
|
|
6214
|
-
if (types.isAsyncFunction(input.setup))
|
|
6215
|
-
throw new TypeError("Extension setup must be synchronous.");
|
|
6216
|
-
const manifest = readDataRecord(input.manifest, "Extension manifest");
|
|
6217
|
-
if (Object.keys(manifest).some(
|
|
6218
|
-
(key) => !["version", "name", "capabilities", "globals", "modules"].includes(key)
|
|
6219
|
-
))
|
|
6220
|
-
throw new TypeError("Unknown extension manifest field.");
|
|
6221
|
-
if (manifest.version !== 1) throw new TypeError("Unsupported extension manifest version.");
|
|
6222
|
-
if (typeof manifest.name !== "string" || manifest.name.length === 0 || manifest.name.length > 256)
|
|
6223
|
-
throw new TypeError("Extension name must be a nonempty bounded string.");
|
|
6224
|
-
const modules = /* @__PURE__ */ Object.create(null);
|
|
6225
|
-
for (const [name, exports] of Object.entries(
|
|
6226
|
-
readDataRecord(manifest.modules ?? {}, "Extension modules")
|
|
6227
|
-
)) {
|
|
6228
|
-
if (name.length === 0) throw new TypeError("Module names must be nonempty.");
|
|
6229
|
-
modules[name] = readStringList(exports, `Module '${name}' exports`);
|
|
6230
|
-
}
|
|
6231
|
-
const extension = Object.freeze({
|
|
6232
|
-
manifest: Object.freeze({
|
|
6233
|
-
version: 1,
|
|
6234
|
-
name: manifest.name,
|
|
6235
|
-
capabilities: readStringList(manifest.capabilities ?? [], "Extension capabilities"),
|
|
6236
|
-
globals: readStringList(manifest.globals ?? [], "Extension globals"),
|
|
6237
|
-
modules: Object.freeze(modules)
|
|
6238
|
-
})
|
|
6239
|
-
});
|
|
6240
|
-
definitions.set(extension, input.setup);
|
|
6241
|
-
return extension;
|
|
6242
|
-
}
|
|
6243
|
-
function getExtensionSetup(extension) {
|
|
6244
|
-
const setup = definitions.get(extension);
|
|
6245
|
-
if (setup === void 0) throw new TypeError("Extensions must be created by defineExtension.");
|
|
6246
|
-
return setup;
|
|
6247
|
-
}
|
|
6248
|
-
|
|
6249
6168
|
// packages/safe-js/src/observability/otel.ts
|
|
6250
6169
|
var noopOtelSink = {
|
|
6251
6170
|
startSpan: () => noopOtelSpan,
|
|
@@ -6337,6 +6256,87 @@ function readErrorMessage(error) {
|
|
|
6337
6256
|
return error instanceof Error ? error.message : String(error);
|
|
6338
6257
|
}
|
|
6339
6258
|
|
|
6259
|
+
// packages/safe-js/src/extensions.ts
|
|
6260
|
+
import { types } from "node:util";
|
|
6261
|
+
var definitions = /* @__PURE__ */ new WeakMap();
|
|
6262
|
+
function readDataRecord(value, label) {
|
|
6263
|
+
if (typeof value !== "object" || value === null || types.isProxy(value)) {
|
|
6264
|
+
throw new TypeError(`${label} must be a plain data record.`);
|
|
6265
|
+
}
|
|
6266
|
+
const prototype = Object.getPrototypeOf(value);
|
|
6267
|
+
if (prototype !== null && prototype !== Object.prototype) {
|
|
6268
|
+
throw new TypeError(`${label} must be a plain data record.`);
|
|
6269
|
+
}
|
|
6270
|
+
const keys = Reflect.ownKeys(value);
|
|
6271
|
+
if (keys.length > 4096) throw new RangeError(`${label} has too many fields.`);
|
|
6272
|
+
const result = /* @__PURE__ */ Object.create(null);
|
|
6273
|
+
for (const key of keys) {
|
|
6274
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
6275
|
+
if (typeof key !== "string" || !("value" in descriptor)) {
|
|
6276
|
+
throw new TypeError(`${label} requires string-keyed data properties, not accessors.`);
|
|
6277
|
+
}
|
|
6278
|
+
result[key] = descriptor.value;
|
|
6279
|
+
}
|
|
6280
|
+
return result;
|
|
6281
|
+
}
|
|
6282
|
+
function readStringList(value, label) {
|
|
6283
|
+
if (!Array.isArray(value) || types.isProxy(value) || value.length > 4096) {
|
|
6284
|
+
throw new TypeError(`${label} must be a bounded string array.`);
|
|
6285
|
+
}
|
|
6286
|
+
const result = [];
|
|
6287
|
+
for (let index = 0; index < value.length; index++) {
|
|
6288
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, String(index));
|
|
6289
|
+
if (descriptor === void 0 || !("value" in descriptor) || typeof descriptor.value !== "string" || descriptor.value.length === 0) {
|
|
6290
|
+
throw new TypeError(`${label} requires nonempty string data properties.`);
|
|
6291
|
+
}
|
|
6292
|
+
if (result.includes(descriptor.value))
|
|
6293
|
+
throw new TypeError(`${label} contains a duplicate name.`);
|
|
6294
|
+
result.push(descriptor.value);
|
|
6295
|
+
}
|
|
6296
|
+
if (Reflect.ownKeys(value).length !== result.length + 1)
|
|
6297
|
+
throw new TypeError(`${label} has unexpected fields.`);
|
|
6298
|
+
return Object.freeze(result);
|
|
6299
|
+
}
|
|
6300
|
+
function defineExtension(definition) {
|
|
6301
|
+
const input = readDataRecord(definition, "Extension definition");
|
|
6302
|
+
if (Object.keys(input).some((key) => key !== "manifest" && key !== "setup"))
|
|
6303
|
+
throw new TypeError("Unknown extension definition field.");
|
|
6304
|
+
if (typeof input.setup !== "function") throw new TypeError("Extension setup must be a function.");
|
|
6305
|
+
if (types.isAsyncFunction(input.setup))
|
|
6306
|
+
throw new TypeError("Extension setup must be synchronous.");
|
|
6307
|
+
const manifest = readDataRecord(input.manifest, "Extension manifest");
|
|
6308
|
+
if (Object.keys(manifest).some(
|
|
6309
|
+
(key) => !["version", "name", "capabilities", "globals", "modules"].includes(key)
|
|
6310
|
+
))
|
|
6311
|
+
throw new TypeError("Unknown extension manifest field.");
|
|
6312
|
+
if (manifest.version !== 1) throw new TypeError("Unsupported extension manifest version.");
|
|
6313
|
+
if (typeof manifest.name !== "string" || manifest.name.length === 0 || manifest.name.length > 256)
|
|
6314
|
+
throw new TypeError("Extension name must be a nonempty bounded string.");
|
|
6315
|
+
const modules = /* @__PURE__ */ Object.create(null);
|
|
6316
|
+
for (const [name, exports] of Object.entries(
|
|
6317
|
+
readDataRecord(manifest.modules ?? {}, "Extension modules")
|
|
6318
|
+
)) {
|
|
6319
|
+
if (name.length === 0) throw new TypeError("Module names must be nonempty.");
|
|
6320
|
+
modules[name] = readStringList(exports, `Module '${name}' exports`);
|
|
6321
|
+
}
|
|
6322
|
+
const extension = Object.freeze({
|
|
6323
|
+
manifest: Object.freeze({
|
|
6324
|
+
version: 1,
|
|
6325
|
+
name: manifest.name,
|
|
6326
|
+
capabilities: readStringList(manifest.capabilities ?? [], "Extension capabilities"),
|
|
6327
|
+
globals: readStringList(manifest.globals ?? [], "Extension globals"),
|
|
6328
|
+
modules: Object.freeze(modules)
|
|
6329
|
+
})
|
|
6330
|
+
});
|
|
6331
|
+
definitions.set(extension, input.setup);
|
|
6332
|
+
return extension;
|
|
6333
|
+
}
|
|
6334
|
+
function getExtensionSetup(extension) {
|
|
6335
|
+
const setup = definitions.get(extension);
|
|
6336
|
+
if (setup === void 0) throw new TypeError("Extensions must be created by defineExtension.");
|
|
6337
|
+
return setup;
|
|
6338
|
+
}
|
|
6339
|
+
|
|
6340
6340
|
// packages/safe-js/src/snapshot/policy.ts
|
|
6341
6341
|
var MODULE_PENDING_HOST_CALL_POLICIES = Object.assign(
|
|
6342
6342
|
/* @__PURE__ */ Object.create(null),
|
|
@@ -6583,6 +6583,14 @@ function serializedDateTime(value) {
|
|
|
6583
6583
|
// packages/safe-js/src/interp/internal-symbols.ts
|
|
6584
6584
|
var internalSymbols = /* @__PURE__ */ new Set();
|
|
6585
6585
|
|
|
6586
|
+
// packages/safe-js/src/interp/regexp-properties.ts
|
|
6587
|
+
var regexGuestProperties = /* @__PURE__ */ new WeakMap();
|
|
6588
|
+
function getRegexProperties(value) {
|
|
6589
|
+
const properties = regexGuestProperties.get(value);
|
|
6590
|
+
if (properties === void 0) throw new TypeError("Invalid sandbox RegExp storage.");
|
|
6591
|
+
return properties;
|
|
6592
|
+
}
|
|
6593
|
+
|
|
6586
6594
|
// packages/safe-js/src/interp/accessors.ts
|
|
6587
6595
|
var accessorClosures = /* @__PURE__ */ new WeakMap();
|
|
6588
6596
|
var getterAdapters = /* @__PURE__ */ new WeakMap();
|
|
@@ -7236,6 +7244,96 @@ var wellKnownSymbols = Object.freeze({
|
|
|
7236
7244
|
unscopables: Symbol.unscopables
|
|
7237
7245
|
});
|
|
7238
7246
|
|
|
7247
|
+
// packages/safe-js/src/snapshot/symbols.ts
|
|
7248
|
+
function symbolData(value) {
|
|
7249
|
+
const wellKnown = Object.keys(wellKnownSymbols).find((key) => wellKnownSymbols[key] === value);
|
|
7250
|
+
return {
|
|
7251
|
+
kind: "symbol",
|
|
7252
|
+
...wellKnown === void 0 ? value.description === void 0 ? {} : { description: value.description } : { wellKnown }
|
|
7253
|
+
};
|
|
7254
|
+
}
|
|
7255
|
+
function serializeSymbol(value, heapIds, heap) {
|
|
7256
|
+
let id = heapIds.get(value);
|
|
7257
|
+
if (id === void 0) {
|
|
7258
|
+
id = heapIds.size + 1;
|
|
7259
|
+
heapIds.set(value, id);
|
|
7260
|
+
heap[String(id)] = symbolData(value);
|
|
7261
|
+
}
|
|
7262
|
+
return { kind: "ref", id };
|
|
7263
|
+
}
|
|
7264
|
+
function ownSerializableSymbolKeys(value) {
|
|
7265
|
+
return Object.getOwnPropertySymbols(value).filter((key) => !internalSymbols.has(key));
|
|
7266
|
+
}
|
|
7267
|
+
function serializeSymbolProperties(value, encode) {
|
|
7268
|
+
return ownSerializableSymbolKeys(value).map((key) => {
|
|
7269
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
7270
|
+
if (!("value" in descriptor)) throw new TypeError("Symbol accessor properties cannot be serialized.");
|
|
7271
|
+
return [encode(key), { value: encode(descriptor.value), enumerable: descriptor.enumerable === true, writable: descriptor.writable === true, configurable: descriptor.configurable === true }];
|
|
7272
|
+
});
|
|
7273
|
+
}
|
|
7274
|
+
function restoreSymbolProperties(target, entries, decode) {
|
|
7275
|
+
for (const [key, descriptor] of entries ?? []) {
|
|
7276
|
+
const symbol = decode(key);
|
|
7277
|
+
if (typeof symbol !== "symbol") throw new TypeError("Expected a symbol property key");
|
|
7278
|
+
Object.defineProperty(target, symbol, { ...descriptor, value: decode(descriptor.value) });
|
|
7279
|
+
}
|
|
7280
|
+
}
|
|
7281
|
+
|
|
7282
|
+
// packages/safe-js/src/snapshot/regexp-properties.ts
|
|
7283
|
+
function hasCustomRegexProperties(value) {
|
|
7284
|
+
const properties = getRegexProperties(value);
|
|
7285
|
+
return Reflect.ownKeys(properties).length !== 1 || !Object.isExtensible(properties) || Object.getOwnPropertyDescriptor(properties, "lastIndex")?.writable !== true;
|
|
7286
|
+
}
|
|
7287
|
+
function serializeRegexProperties(value, encode) {
|
|
7288
|
+
if (!hasCustomRegexProperties(value)) return {};
|
|
7289
|
+
const source = getRegexProperties(value);
|
|
7290
|
+
const properties = /* @__PURE__ */ Object.create(null);
|
|
7291
|
+
for (const key of Object.getOwnPropertyNames(source)) {
|
|
7292
|
+
const descriptor = Object.getOwnPropertyDescriptor(source, key);
|
|
7293
|
+
if (!("value" in descriptor)) throw new TypeError("RegExp accessor properties cannot be serialized as data.");
|
|
7294
|
+
properties[key] = {
|
|
7295
|
+
value: encode(descriptor.value),
|
|
7296
|
+
enumerable: descriptor.enumerable === true,
|
|
7297
|
+
configurable: descriptor.configurable === true,
|
|
7298
|
+
writable: descriptor.writable === true
|
|
7299
|
+
};
|
|
7300
|
+
}
|
|
7301
|
+
const symbolEntries = serializeSymbolProperties(source, encode);
|
|
7302
|
+
return {
|
|
7303
|
+
properties,
|
|
7304
|
+
...symbolEntries.length === 0 ? {} : { symbolEntries },
|
|
7305
|
+
...Object.isExtensible(source) ? {} : { extensible: false }
|
|
7306
|
+
};
|
|
7307
|
+
}
|
|
7308
|
+
function validateRegexProperties(data) {
|
|
7309
|
+
const descriptor = (value) => {
|
|
7310
|
+
if (typeof value !== "object" || value === null || Array.isArray(value) || !Object.hasOwn(value, "value") || !["enumerable", "configurable", "writable"].every((key) => Object.hasOwn(value, key) && typeof value[key] === "boolean") || Object.keys(value).some((key) => !["value", "enumerable", "configurable", "writable"].includes(key)))
|
|
7311
|
+
throw new TypeError("Invalid RegExp data property descriptor.");
|
|
7312
|
+
};
|
|
7313
|
+
if (data.extensible !== void 0 && typeof data.extensible !== "boolean")
|
|
7314
|
+
throw new TypeError("Invalid RegExp extensibility.");
|
|
7315
|
+
if (data.properties !== void 0) {
|
|
7316
|
+
if (typeof data.properties !== "object" || data.properties === null || Array.isArray(data.properties))
|
|
7317
|
+
throw new TypeError("Invalid RegExp property data.");
|
|
7318
|
+
for (const entry of Object.values(data.properties)) descriptor(entry);
|
|
7319
|
+
}
|
|
7320
|
+
if (data.symbolEntries !== void 0) {
|
|
7321
|
+
if (!Array.isArray(data.symbolEntries)) throw new TypeError("Invalid RegExp symbol properties.");
|
|
7322
|
+
for (const entry of data.symbolEntries) {
|
|
7323
|
+
if (!Array.isArray(entry) || entry.length !== 2) throw new TypeError("Invalid RegExp symbol property.");
|
|
7324
|
+
descriptor(entry[1]);
|
|
7325
|
+
}
|
|
7326
|
+
}
|
|
7327
|
+
}
|
|
7328
|
+
function restoreRegexProperties(value, data, decode) {
|
|
7329
|
+
validateRegexProperties(data);
|
|
7330
|
+
const properties = getRegexProperties(value);
|
|
7331
|
+
for (const [key, descriptor] of Object.entries(data.properties ?? {}))
|
|
7332
|
+
Object.defineProperty(properties, key, { ...descriptor, value: decode(descriptor.value) });
|
|
7333
|
+
restoreSymbolProperties(properties, data.symbolEntries, decode);
|
|
7334
|
+
if (data.extensible === false) Object.preventExtensions(properties);
|
|
7335
|
+
}
|
|
7336
|
+
|
|
7239
7337
|
// packages/safe-js/src/snapshot/validation.ts
|
|
7240
7338
|
import { types as types5 } from "node:util";
|
|
7241
7339
|
|
|
@@ -7343,6 +7441,11 @@ function walkGraphDepth(root, rootPath, assertDepth) {
|
|
|
7343
7441
|
}
|
|
7344
7442
|
}
|
|
7345
7443
|
function graphEntries(value) {
|
|
7444
|
+
const properties = regexGuestProperties.get(value);
|
|
7445
|
+
if (properties !== void 0) return Reflect.ownKeys(properties).flatMap((key) => {
|
|
7446
|
+
const descriptor = Object.getOwnPropertyDescriptor(properties, key);
|
|
7447
|
+
return "value" in descriptor ? [[`.${String(key)}`, descriptor.value]] : [];
|
|
7448
|
+
});
|
|
7346
7449
|
if (isSandboxBox(value)) return boxedDataProperties(value).map(([key, descriptor]) => [`.${key}`, descriptor.value]);
|
|
7347
7450
|
if (isSandboxArguments(value)) {
|
|
7348
7451
|
return getSandboxArgumentEntries(value).map(([key, entry]) => [`.${key}`, entry]);
|
|
@@ -7497,8 +7600,8 @@ function getSandboxPropertyDescriptor(value, key, budget) {
|
|
|
7497
7600
|
return hostProperties === void 0 ? void 0 : Object.getOwnPropertyDescriptor(hostProperties, key);
|
|
7498
7601
|
let current = value;
|
|
7499
7602
|
let depth = 0;
|
|
7500
|
-
while (typeof current === "object" && current !== null && (Array.isArray(current) || isSandboxDate(current) || isPrototypeRecord(current))) {
|
|
7501
|
-
const properties = isGuestClosure(current) ? getGuestFunctionProperties(current) : current;
|
|
7603
|
+
while (typeof current === "object" && current !== null && (Array.isArray(current) || isSandboxDate(current) || isSandboxRegex(current) || isPrototypeRecord(current))) {
|
|
7604
|
+
const properties = isGuestClosure(current) ? getGuestFunctionProperties(current) : isSandboxRegex(current) ? getRegexProperties(current) : current;
|
|
7502
7605
|
const descriptor = properties === void 0 ? void 0 : Object.getOwnPropertyDescriptor(properties, key);
|
|
7503
7606
|
if (descriptor !== void 0) return descriptor;
|
|
7504
7607
|
current = getSandboxPrototype(current, budget);
|
|
@@ -7514,6 +7617,7 @@ function getSandboxDataProperty(value, key, budget) {
|
|
|
7514
7617
|
let depth = 0;
|
|
7515
7618
|
while (typeof current === "object" && current !== null) {
|
|
7516
7619
|
if (isGuestHostObject(current)) return typeof key === "symbol" ? void 0 : getHostObjectMember(current, String(key));
|
|
7620
|
+
if (isSandboxRegex(current)) return Object.getOwnPropertyDescriptor(getRegexProperties(current), key)?.value;
|
|
7517
7621
|
if (isGuestClosure(current)) {
|
|
7518
7622
|
const entry = getGuestFunctionProperty(current, key);
|
|
7519
7623
|
if (entry !== void 0 || Object.hasOwn(current.properties ?? {}, key)) return entry;
|
|
@@ -7676,34 +7780,6 @@ function decodeFloat32Storage(value, resolve) {
|
|
|
7676
7780
|
return new Float32Array(buffer, Number(value.byteOffset), Number(value.length));
|
|
7677
7781
|
}
|
|
7678
7782
|
|
|
7679
|
-
// packages/safe-js/src/snapshot/symbols.ts
|
|
7680
|
-
function symbolData(value) {
|
|
7681
|
-
const wellKnown = Object.keys(wellKnownSymbols).find((key) => wellKnownSymbols[key] === value);
|
|
7682
|
-
return {
|
|
7683
|
-
kind: "symbol",
|
|
7684
|
-
...wellKnown === void 0 ? value.description === void 0 ? {} : { description: value.description } : { wellKnown }
|
|
7685
|
-
};
|
|
7686
|
-
}
|
|
7687
|
-
function serializeSymbol(value, heapIds, heap) {
|
|
7688
|
-
let id = heapIds.get(value);
|
|
7689
|
-
if (id === void 0) {
|
|
7690
|
-
id = heapIds.size + 1;
|
|
7691
|
-
heapIds.set(value, id);
|
|
7692
|
-
heap[String(id)] = symbolData(value);
|
|
7693
|
-
}
|
|
7694
|
-
return { kind: "ref", id };
|
|
7695
|
-
}
|
|
7696
|
-
function ownSerializableSymbolKeys(value) {
|
|
7697
|
-
return Object.getOwnPropertySymbols(value).filter((key) => !internalSymbols.has(key));
|
|
7698
|
-
}
|
|
7699
|
-
function serializeSymbolProperties(value, encode) {
|
|
7700
|
-
return ownSerializableSymbolKeys(value).map((key) => {
|
|
7701
|
-
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
7702
|
-
if (!("value" in descriptor)) throw new TypeError("Symbol accessor properties cannot be serialized.");
|
|
7703
|
-
return [encode(key), { value: encode(descriptor.value), enumerable: descriptor.enumerable === true, writable: descriptor.writable === true, configurable: descriptor.configurable === true }];
|
|
7704
|
-
});
|
|
7705
|
-
}
|
|
7706
|
-
|
|
7707
7783
|
// packages/safe-js/src/snapshot/date-properties.ts
|
|
7708
7784
|
function serializeDate(value, encode) {
|
|
7709
7785
|
const properties = /* @__PURE__ */ Object.create(null);
|
|
@@ -7813,7 +7889,7 @@ function serializeDumpValue(value, path, state) {
|
|
|
7813
7889
|
if (hasGuestObjectState(value)) {
|
|
7814
7890
|
throw new TypeError("Guest function properties and prototype links cannot be serialized.");
|
|
7815
7891
|
}
|
|
7816
|
-
if (isSandboxBox(value) || isSandboxDate(value) || isFloat32Array(value)) return serializeHeapReference(value, path, state);
|
|
7892
|
+
if (isSandboxRegex(value) && hasCustomRegexProperties(value) || isSandboxBox(value) || isSandboxDate(value) || isFloat32Array(value)) return serializeHeapReference(value, path, state);
|
|
7817
7893
|
if (Array.isArray(value)) {
|
|
7818
7894
|
const reference2 = serializeHeapReference(value, path, state);
|
|
7819
7895
|
if (reference2 !== void 0) {
|
|
@@ -7837,7 +7913,20 @@ function serializeHeapReference(value, path, state) {
|
|
|
7837
7913
|
}
|
|
7838
7914
|
if (!state.serializedHeapIds.has(id)) {
|
|
7839
7915
|
state.serializedHeapIds.add(id);
|
|
7840
|
-
if (
|
|
7916
|
+
if (isSandboxRegex(value) && hasCustomRegexProperties(value)) {
|
|
7917
|
+
const encode = (entry) => {
|
|
7918
|
+
const serialized = serializeDumpValue(entry, `${path}.<regex-property>`, state);
|
|
7919
|
+
if (serialized === SKIP_VALUE) throw new TypeError("Unsupported RegExp property in public dump.");
|
|
7920
|
+
return serialized;
|
|
7921
|
+
};
|
|
7922
|
+
state.heap[String(id)] = {
|
|
7923
|
+
kind: "regex-object",
|
|
7924
|
+
source: value.source,
|
|
7925
|
+
flags: value.flags,
|
|
7926
|
+
lastIndex: encode(value.lastIndex),
|
|
7927
|
+
...serializeRegexProperties(value, encode)
|
|
7928
|
+
};
|
|
7929
|
+
} else if (isSandboxBox(value)) {
|
|
7841
7930
|
state.heap[String(id)] = encodeBoxedData(value, (entry, key) => {
|
|
7842
7931
|
if (Object.is(entry, -0)) return { kind: "number", value: "-0" };
|
|
7843
7932
|
const serialized = serializeDumpValue(entry, `${path}.${key}`, state);
|
|
@@ -7916,7 +8005,7 @@ function indexHeapContainers(snapshot) {
|
|
|
7916
8005
|
const heapIds = /* @__PURE__ */ new Map();
|
|
7917
8006
|
let nextId = 1;
|
|
7918
8007
|
for (const [value, stat2] of stats.entries()) {
|
|
7919
|
-
if (stat2.count > 1 || stat2.cyclic || ownSerializableSymbolKeys(value).length > 0 || isSandboxBox(value) || isSandboxDate(value) || isFloat32Array(value) || Array.isArray(value) && requiresArrayEntries(value) || isSandboxArguments(value) || sandboxErrorTypes.has(value)) {
|
|
8008
|
+
if (stat2.count > 1 || stat2.cyclic || ownSerializableSymbolKeys(value).length > 0 || isSandboxBox(value) || isSandboxRegex(value) && hasCustomRegexProperties(value) || isSandboxDate(value) || isFloat32Array(value) || Array.isArray(value) && requiresArrayEntries(value) || isSandboxArguments(value) || sandboxErrorTypes.has(value)) {
|
|
7920
8009
|
heapIds.set(value, nextId);
|
|
7921
8010
|
nextId += 1;
|
|
7922
8011
|
}
|
|
@@ -7949,7 +8038,10 @@ function collectContainerStats(value, stats, ancestors) {
|
|
|
7949
8038
|
}
|
|
7950
8039
|
stat2.expanded = true;
|
|
7951
8040
|
ancestors.add(value);
|
|
7952
|
-
const entries =
|
|
8041
|
+
const entries = isSandboxRegex(value) ? Reflect.ownKeys(getRegexProperties(value)).flatMap((key) => {
|
|
8042
|
+
const descriptor = Object.getOwnPropertyDescriptor(getRegexProperties(value), key);
|
|
8043
|
+
return "value" in descriptor ? [descriptor.value] : [];
|
|
8044
|
+
}) : isSandboxDate(value) ? dateDataProperties(value).flatMap(([key, descriptor]) => typeof key === "string" ? [descriptor.value] : []) : isSandboxBox(value) ? boxedDataProperties(value).map(([, descriptor]) => descriptor.value) : isSandboxArguments(value) ? getSandboxArgumentEntries(value).map(([, entry]) => entry) : getEnumerableDataValues(value);
|
|
7953
8045
|
for (const entry of entries) {
|
|
7954
8046
|
collectContainerStats(entry, stats, ancestors);
|
|
7955
8047
|
}
|
|
@@ -8069,6 +8161,10 @@ function validateDumpHeap(root, state) {
|
|
|
8069
8161
|
const entry = requireRecord(value, path);
|
|
8070
8162
|
validateErrorType(entry, path);
|
|
8071
8163
|
validateSymbolEntries(entry, path, state, heap);
|
|
8164
|
+
if (entry.kind === "regex-object") {
|
|
8165
|
+
validateTaggedValue(entry, path, state);
|
|
8166
|
+
continue;
|
|
8167
|
+
}
|
|
8072
8168
|
if (entry.kind === "boxed") {
|
|
8073
8169
|
validateBoxedRecord(entry, path, heap);
|
|
8074
8170
|
continue;
|
|
@@ -8200,6 +8296,11 @@ function validateTaggedValue(record2, path, state) {
|
|
|
8200
8296
|
requireString(record2.source, `${path}.source`, state.limits);
|
|
8201
8297
|
requireString(record2.flags, `${path}.flags`, state.limits);
|
|
8202
8298
|
if (!Object.hasOwn(record2, "lastIndex")) fail("invalidValue", `${path}.lastIndex`, "missing regex cursor");
|
|
8299
|
+
try {
|
|
8300
|
+
validateRegexProperties(record2);
|
|
8301
|
+
} catch {
|
|
8302
|
+
fail("invalidValue", path, "invalid RegExp property data");
|
|
8303
|
+
}
|
|
8203
8304
|
return;
|
|
8204
8305
|
case "array":
|
|
8205
8306
|
case "arguments":
|
|
@@ -8249,7 +8350,7 @@ function validateGeneratorShape(record2, path, state) {
|
|
|
8249
8350
|
}
|
|
8250
8351
|
function validateSymbolEntries(record2, path, state, heap) {
|
|
8251
8352
|
if (record2.symbolEntries === void 0) return;
|
|
8252
|
-
if (record2.kind !== "object" && record2.kind !== "array" && record2.kind !== "date" && record2.kind !== "boxed")
|
|
8353
|
+
if (record2.kind !== "object" && record2.kind !== "array" && record2.kind !== "date" && record2.kind !== "boxed" && record2.kind !== "regex-object")
|
|
8253
8354
|
fail("invalidValue", `${path}.symbolEntries`, "symbol properties are unsupported for this heap kind");
|
|
8254
8355
|
const entries = requireArray(record2.symbolEntries, `${path}.symbolEntries`, state);
|
|
8255
8356
|
const keys = /* @__PURE__ */ new Set();
|
|
@@ -9854,6 +9955,9 @@ function formatNumber(value, methodName, argument, budget) {
|
|
|
9854
9955
|
return budget.allocateString(result);
|
|
9855
9956
|
}
|
|
9856
9957
|
|
|
9958
|
+
// packages/safe-js/src/interp/methods/string.ts
|
|
9959
|
+
import { types as types6 } from "node:util";
|
|
9960
|
+
|
|
9857
9961
|
// packages/safe-js/src/interp/regex/engine.ts
|
|
9858
9962
|
function matchRegex(pattern, input, lastIndex = 0) {
|
|
9859
9963
|
const startIndex = pattern.flags.global ? normalizeLastIndex(lastIndex) : 0;
|
|
@@ -10138,10 +10242,11 @@ function escapeRegexSource(source, budget) {
|
|
|
10138
10242
|
return budget === void 0 ? text : budget.allocateString(text);
|
|
10139
10243
|
}
|
|
10140
10244
|
function setRegexMember(target, property, value) {
|
|
10141
|
-
|
|
10245
|
+
const properties = getRegexProperties(target);
|
|
10246
|
+
if (!Object.hasOwn(properties, property) && (property === "source" || property === "flags" || Object.hasOwn(regexFlagProperties, property))) {
|
|
10142
10247
|
throw new TypeError(`RegExp#${String(property)} is not writable.`);
|
|
10143
10248
|
}
|
|
10144
|
-
|
|
10249
|
+
if (!Reflect.set(properties, property, value)) throw new TypeError(`RegExp#${String(property)} is not writable.`);
|
|
10145
10250
|
}
|
|
10146
10251
|
async function callRegexMethod(target, methodName, args, budget, context) {
|
|
10147
10252
|
if (target === null || typeof target !== "object" || methodName === "exec" && !isSandboxRegex(target)) {
|
|
@@ -10280,15 +10385,39 @@ function callStringMethod(value, methodName, args, budget, callClosure = async (
|
|
|
10280
10385
|
if (value === null || value === void 0)
|
|
10281
10386
|
throw new TypeError(`String#${methodName} requires a non-null receiver.`);
|
|
10282
10387
|
const fallback = () => typeof value === "string" ? callStringMethodBody(value, methodName, args, budget, callClosure, parent, context) : Promise.resolve(sandboxString(value, budget, context)).then((string) => callStringMethodBody(string, methodName, args, budget, callClosure, parent, context));
|
|
10283
|
-
const symbol = methodName === "match" ? Symbol.match : methodName === "search" ? Symbol.search : methodName === "split" ? Symbol.split : void 0;
|
|
10388
|
+
const symbol = methodName === "match" ? Symbol.match : methodName === "search" ? Symbol.search : methodName === "matchAll" ? Symbol.matchAll : methodName === "replace" || methodName === "replaceAll" ? Symbol.replace : methodName === "split" ? Symbol.split : void 0;
|
|
10284
10389
|
const pattern = args[0];
|
|
10390
|
+
if (symbol !== void 0 && types6.isRegExp(pattern))
|
|
10391
|
+
throw new TypeError(`String#${methodName} does not accept unbranded host RegExp values.`);
|
|
10285
10392
|
if (symbol === void 0 || pattern === null || pattern === void 0) return fallback();
|
|
10286
10393
|
const applyHook = (hook) => {
|
|
10287
10394
|
if (hook === null || hook === void 0) return fallback();
|
|
10288
10395
|
if (!isSandboxClosure(hook)) throw new TypeError(`String#${methodName} symbol hook must be callable.`);
|
|
10289
|
-
return invokeBuiltinClosure(hook,
|
|
10396
|
+
return invokeBuiltinClosure(hook, symbol === Symbol.split || symbol === Symbol.replace ? [value, args[1]] : [value], budget, context, pattern);
|
|
10290
10397
|
};
|
|
10291
|
-
|
|
10398
|
+
const readProperty = (key) => context?.getProperty !== void 0 ? context.getProperty(pattern, key) : key === "flags" && isSandboxRegex(pattern) && getSandboxPropertyDescriptor(pattern, key, budget) === void 0 ? pattern.flags : getSandboxDataProperty(pattern, key, budget);
|
|
10399
|
+
const dispatch = () => {
|
|
10400
|
+
const hook = readProperty(symbol);
|
|
10401
|
+
return hook instanceof Promise ? hook.then(applyHook) : applyHook(hook);
|
|
10402
|
+
};
|
|
10403
|
+
if ((methodName === "replaceAll" || methodName === "matchAll") && (typeof pattern === "object" || typeof pattern === "function")) {
|
|
10404
|
+
const checkFlags = (flags) => {
|
|
10405
|
+
const checkText = (text2) => {
|
|
10406
|
+
if (!text2.includes("g")) throw new TypeError(`String#${methodName} requires a global regex.`);
|
|
10407
|
+
return dispatch();
|
|
10408
|
+
};
|
|
10409
|
+
const text = sandboxString(flags, budget, context);
|
|
10410
|
+
return typeof text === "string" ? checkText(text) : text.then(checkText);
|
|
10411
|
+
};
|
|
10412
|
+
const checkMatch = (match2) => {
|
|
10413
|
+
if (!(match2 === void 0 ? isSandboxRegex(pattern) : Boolean(match2))) return dispatch();
|
|
10414
|
+
const flags = readProperty("flags");
|
|
10415
|
+
return flags instanceof Promise ? flags.then(checkFlags) : checkFlags(flags);
|
|
10416
|
+
};
|
|
10417
|
+
const match = readProperty(Symbol.match);
|
|
10418
|
+
return match instanceof Promise ? match.then(checkMatch) : checkMatch(match);
|
|
10419
|
+
}
|
|
10420
|
+
return dispatch();
|
|
10292
10421
|
}
|
|
10293
10422
|
function callStringMethodBody(value, methodName, args, budget, callClosure = async (closure, closureArgs) => await closure.call(closureArgs), parent, context) {
|
|
10294
10423
|
if (methodName === "concat" && args.some((argument) => argument !== null && typeof argument === "object")) {
|
|
@@ -10333,7 +10462,7 @@ function callStringMethodBody(value, methodName, args, budget, callClosure = asy
|
|
|
10333
10462
|
return callReplaceLikeMethod(value, methodName, args, budget, callClosure, context);
|
|
10334
10463
|
}
|
|
10335
10464
|
const regex = args[0];
|
|
10336
|
-
if (isSandboxRegex(regex) && regex.lastIndex !== null && typeof regex.lastIndex === "object" && (methodName === "match" && !regex.flags.includes("g") || methodName === "matchAll"
|
|
10465
|
+
if (isSandboxRegex(regex) && regex.lastIndex !== null && typeof regex.lastIndex === "object" && (methodName === "match" && !regex.flags.includes("g") || methodName === "matchAll")) {
|
|
10337
10466
|
return callStringRegexCursor(value, methodName, regex, budget, parent, context);
|
|
10338
10467
|
}
|
|
10339
10468
|
if ((methodName === "match" || methodName === "matchAll" || methodName === "search") && !isSandboxRegex(args[0])) {
|
|
@@ -10465,20 +10594,26 @@ async function callConcat(value, args, budget, context) {
|
|
|
10465
10594
|
function callReplaceLikeMethod(value, methodName, args, budget, callClosure, context) {
|
|
10466
10595
|
const search = args[0];
|
|
10467
10596
|
const replacement = args[1];
|
|
10468
|
-
|
|
10469
|
-
|
|
10470
|
-
|
|
10471
|
-
|
|
10597
|
+
const useRegex = isSandboxRegex(search) && getSandboxPropertyDescriptor(search, Symbol.replace, budget) === void 0;
|
|
10598
|
+
if (!useRegex && typeof search !== "string" || typeof replacement !== "string" && !isSandboxClosure(replacement)) {
|
|
10599
|
+
return (async () => {
|
|
10600
|
+
let normalizedSearch;
|
|
10601
|
+
let normalizedReplacement;
|
|
10602
|
+
const release = retainValues(budget, () => [normalizedSearch, normalizedReplacement]);
|
|
10603
|
+
try {
|
|
10604
|
+
normalizedSearch = useRegex ? search : await sandboxString(search, budget, context);
|
|
10605
|
+
normalizedReplacement = isSandboxClosure(replacement) ? replacement : await sandboxString(replacement, budget, context);
|
|
10606
|
+
return await callReplaceLikeMethod(value, methodName, [normalizedSearch, normalizedReplacement], budget, callClosure, context);
|
|
10607
|
+
} finally {
|
|
10608
|
+
release();
|
|
10609
|
+
}
|
|
10610
|
+
})();
|
|
10472
10611
|
}
|
|
10473
10612
|
if (isSandboxRegex(search)) {
|
|
10474
|
-
if (methodName === "replaceAll" && !search.flags.includes("g")) {
|
|
10475
|
-
throw new TypeError("String#replaceAll requires a global regex.");
|
|
10476
|
-
}
|
|
10477
10613
|
return replaceRegex(
|
|
10478
10614
|
value,
|
|
10479
10615
|
search,
|
|
10480
10616
|
replacement,
|
|
10481
|
-
methodName === "replaceAll",
|
|
10482
10617
|
budget,
|
|
10483
10618
|
callClosure,
|
|
10484
10619
|
context
|
|
@@ -10498,14 +10633,14 @@ function callReplaceLikeMethod(value, methodName, args, budget, callClosure, con
|
|
|
10498
10633
|
callClosure
|
|
10499
10634
|
);
|
|
10500
10635
|
}
|
|
10501
|
-
async function replaceRegex(value, regex, replacement,
|
|
10636
|
+
async function replaceRegex(value, regex, replacement, budget, callClosure, context) {
|
|
10502
10637
|
if (regex.flags.includes("g")) regex.lastIndex = 0;
|
|
10503
10638
|
const cursor = regex.lastIndex;
|
|
10504
10639
|
const retained = {};
|
|
10505
10640
|
budget.setRetainedValues(retained, () => [value, regex, cursor, replacement]);
|
|
10506
10641
|
try {
|
|
10507
10642
|
const lastIndex = await sandboxNumber(cursor, budget, context);
|
|
10508
|
-
const matches = collectRegexMatches(regex, value,
|
|
10643
|
+
const matches = collectRegexMatches(regex, value, regex.flags.includes("g"), void 0, lastIndex);
|
|
10509
10644
|
let result = "";
|
|
10510
10645
|
let copiedThrough = 0;
|
|
10511
10646
|
for (const match of matches) {
|
|
@@ -10672,13 +10807,11 @@ function callMatchLikeMethod(value, methodName, args, compilation, lastIndex) {
|
|
|
10672
10807
|
if (!Object.is(regex.lastIndex, lastIndex2)) regex.lastIndex = lastIndex2;
|
|
10673
10808
|
return match?.index ?? -1;
|
|
10674
10809
|
}
|
|
10675
|
-
if (methodName === "matchAll" && !regex.flags.includes("g"))
|
|
10676
|
-
throw new TypeError("String#matchAll requires a global regex.");
|
|
10677
10810
|
if (methodName === "match" && !regex.flags.includes("g"))
|
|
10678
10811
|
return toMatchArray(executeRegex(regex, value, lastIndex ?? Number(regex.lastIndex)), value);
|
|
10679
10812
|
if (methodName === "match") regex.lastIndex = 0;
|
|
10680
10813
|
const matcher = methodName === "matchAll" ? createSandboxRegex(regex.source, regex.flags, normalizeLastIndex(lastIndex ?? Number(regex.lastIndex)), compilation) : regex;
|
|
10681
|
-
const matches = collectRegexMatches(matcher, value,
|
|
10814
|
+
const matches = collectRegexMatches(matcher, value, matcher.flags.includes("g"), compilation.owner?.budget, Number(matcher.lastIndex));
|
|
10682
10815
|
if (methodName === "match" && matches.length === 0) return null;
|
|
10683
10816
|
return methodName === "match" ? matches.map((match) => match.text) : matches.map((match) => toMatchArray(match, value));
|
|
10684
10817
|
}
|
|
@@ -10953,14 +11086,14 @@ function createObjectArrayGlobals(options) {
|
|
|
10953
11086
|
call: ([value]) => {
|
|
10954
11087
|
if (isGuestHostObject(value))
|
|
10955
11088
|
throw new TypeError("Live host objects cannot be made non-extensible.");
|
|
10956
|
-
Object.preventExtensions(isGuestClosure(value) ? materializeFunctionProperties(value) : value);
|
|
11089
|
+
Object.preventExtensions(isGuestClosure(value) ? materializeFunctionProperties(value) : isSandboxRegex(value) ? getRegexProperties(value) : value);
|
|
10957
11090
|
return value;
|
|
10958
11091
|
},
|
|
10959
11092
|
name: "preventExtensions"
|
|
10960
11093
|
}),
|
|
10961
11094
|
isExtensible: createSandboxClosure({
|
|
10962
11095
|
sandbox: true,
|
|
10963
|
-
call: ([value]) => Object.isExtensible(isGuestClosure(value) ? materializeFunctionProperties(value) : value),
|
|
11096
|
+
call: ([value]) => Object.isExtensible(isGuestClosure(value) ? materializeFunctionProperties(value) : isSandboxRegex(value) ? getRegexProperties(value) : value),
|
|
10964
11097
|
name: "isExtensible"
|
|
10965
11098
|
}),
|
|
10966
11099
|
seal: createSandboxClosure({
|
|
@@ -10968,14 +11101,14 @@ function createObjectArrayGlobals(options) {
|
|
|
10968
11101
|
call: ([value]) => {
|
|
10969
11102
|
if (isGuestHostObject(value))
|
|
10970
11103
|
throw new TypeError("Live host objects cannot be sealed.");
|
|
10971
|
-
Object.seal(isGuestClosure(value) ? materializeFunctionProperties(value) : value);
|
|
11104
|
+
Object.seal(isGuestClosure(value) ? materializeFunctionProperties(value) : isSandboxRegex(value) ? getRegexProperties(value) : value);
|
|
10972
11105
|
return value;
|
|
10973
11106
|
},
|
|
10974
11107
|
name: "seal"
|
|
10975
11108
|
}),
|
|
10976
11109
|
isSealed: createSandboxClosure({
|
|
10977
11110
|
sandbox: true,
|
|
10978
|
-
call: ([value]) => Object.isSealed(isGuestClosure(value) ? materializeFunctionProperties(value) : value),
|
|
11111
|
+
call: ([value]) => Object.isSealed(isGuestClosure(value) ? materializeFunctionProperties(value) : isSandboxRegex(value) ? getRegexProperties(value) : value),
|
|
10979
11112
|
name: "isSealed"
|
|
10980
11113
|
}),
|
|
10981
11114
|
freeze: createSandboxClosure({
|
|
@@ -10984,7 +11117,7 @@ function createObjectArrayGlobals(options) {
|
|
|
10984
11117
|
if (isGuestHostObject(value))
|
|
10985
11118
|
throw new TypeError("Live host objects cannot be frozen.");
|
|
10986
11119
|
if (typeof value === "object" && value !== null) {
|
|
10987
|
-
Object.freeze(isGuestClosure(value) ? materializeFunctionProperties(value) : value);
|
|
11120
|
+
Object.freeze(isGuestClosure(value) ? materializeFunctionProperties(value) : isSandboxRegex(value) ? getRegexProperties(value) : value);
|
|
10988
11121
|
}
|
|
10989
11122
|
return value;
|
|
10990
11123
|
},
|
|
@@ -10992,7 +11125,7 @@ function createObjectArrayGlobals(options) {
|
|
|
10992
11125
|
}),
|
|
10993
11126
|
isFrozen: createSandboxClosure({
|
|
10994
11127
|
sandbox: true,
|
|
10995
|
-
call: ([value]) => Object.isFrozen(isGuestClosure(value) ? materializeFunctionProperties(value) : value),
|
|
11128
|
+
call: ([value]) => Object.isFrozen(isGuestClosure(value) ? materializeFunctionProperties(value) : isSandboxRegex(value) ? getRegexProperties(value) : value),
|
|
10996
11129
|
name: "isFrozen"
|
|
10997
11130
|
}),
|
|
10998
11131
|
assign: createSandboxClosure({
|
|
@@ -11196,6 +11329,7 @@ function assignSandboxValues(target, sources, budget, context) {
|
|
|
11196
11329
|
})();
|
|
11197
11330
|
}
|
|
11198
11331
|
function objectProperties(value, mutable = false) {
|
|
11332
|
+
if (isSandboxRegex(value)) return getRegexProperties(value);
|
|
11199
11333
|
if (isSandboxDate(value)) {
|
|
11200
11334
|
return value;
|
|
11201
11335
|
}
|
|
@@ -15464,7 +15598,7 @@ async function evaluateDeleteExpression(node, context) {
|
|
|
15464
15598
|
}
|
|
15465
15599
|
throw new TypeError("Cannot delete properties of null or undefined.");
|
|
15466
15600
|
}
|
|
15467
|
-
if (!isIndexableSandboxValue(member.object)) {
|
|
15601
|
+
if (!isIndexableSandboxValue(member.object) && !isSandboxRegex(member.object)) {
|
|
15468
15602
|
throw new TypeError("Unary operator 'delete' requires a sandbox object property.");
|
|
15469
15603
|
}
|
|
15470
15604
|
const property = await toPropertyKey(member.property, context.budget, createCoercionContext(context));
|
|
@@ -15867,10 +16001,10 @@ async function evaluateMemberCallExpression(node, context) {
|
|
|
15867
16001
|
member.object
|
|
15868
16002
|
);
|
|
15869
16003
|
}
|
|
15870
|
-
if (isSandboxRegex(member.object)
|
|
16004
|
+
if (isSandboxRegex(member.object)) {
|
|
15871
16005
|
return evaluateResolvedCallExpression(
|
|
15872
16006
|
node,
|
|
15873
|
-
|
|
16007
|
+
await getPropertyValue(member.object, member.property, context),
|
|
15874
16008
|
context,
|
|
15875
16009
|
member.object
|
|
15876
16010
|
);
|
|
@@ -16371,7 +16505,6 @@ function setSandboxProperty(target, property, value, budget, checkInherited = tr
|
|
|
16371
16505
|
return;
|
|
16372
16506
|
}
|
|
16373
16507
|
if (isSandboxRegex(target)) {
|
|
16374
|
-
if (typeof property === "symbol") throw new TypeError("RegExp symbol properties are not yet supported.");
|
|
16375
16508
|
setRegexMember(target, property, value);
|
|
16376
16509
|
return;
|
|
16377
16510
|
}
|
|
@@ -16433,6 +16566,7 @@ function setSuperProperty(base, receiver, key, value, context) {
|
|
|
16433
16566
|
function deleteSandboxProperty(target, property) {
|
|
16434
16567
|
if (isGuestHostObject(target)) return deleteHostObjectMember(target, String(property));
|
|
16435
16568
|
if (isGuestClosure(target)) target = materializeFunctionProperties(target);
|
|
16569
|
+
if (isSandboxRegex(target)) target = getRegexProperties(target);
|
|
16436
16570
|
if (Array.isArray(target)) {
|
|
16437
16571
|
assertCollectionMutable(target);
|
|
16438
16572
|
}
|
|
@@ -17141,7 +17275,8 @@ function encodeReplayData(value, options = {}) {
|
|
|
17141
17275
|
kind: "regex",
|
|
17142
17276
|
source: entry.source,
|
|
17143
17277
|
flags: entry.flags,
|
|
17144
|
-
lastIndex: child(entry.lastIndex, "lastIndex")
|
|
17278
|
+
lastIndex: child(entry.lastIndex, "lastIndex"),
|
|
17279
|
+
...serializeRegexProperties(entry, (value2) => child(value2, "<regex-property>"))
|
|
17145
17280
|
};
|
|
17146
17281
|
} else if (isSandboxArguments(entry)) {
|
|
17147
17282
|
nodes[id] = { kind: "arguments", data: serializeArguments(entry, child) };
|
|
@@ -17344,6 +17479,7 @@ function decodeReplayData(input, options = {}, parent) {
|
|
|
17344
17479
|
const result3 = createSandboxRegex(node.source, node.flags, 0, compilation);
|
|
17345
17480
|
restored.set(id, result3);
|
|
17346
17481
|
result3.lastIndex = child(own(node, "lastIndex"));
|
|
17482
|
+
restoreRegexProperties(result3, node, child);
|
|
17347
17483
|
return result3;
|
|
17348
17484
|
}
|
|
17349
17485
|
if (kind === "arguments") {
|
|
@@ -18826,7 +18962,7 @@ function hasOwnSandboxProperty(value, key, enumerable) {
|
|
|
18826
18962
|
properties = value.properties ?? /* @__PURE__ */ Object.create(null);
|
|
18827
18963
|
} else if (isSandboxMap(value) || isSandboxSet(value) || isSandboxPromise(value) || isSandboxGenerator(value))
|
|
18828
18964
|
return false;
|
|
18829
|
-
else if (isSandboxRegex(value))
|
|
18965
|
+
else if (isSandboxRegex(value)) properties = getRegexProperties(value);
|
|
18830
18966
|
else properties = Object(value);
|
|
18831
18967
|
const descriptor = Object.getOwnPropertyDescriptor(properties, key);
|
|
18832
18968
|
return descriptor !== void 0 && (!enumerable || descriptor.enumerable === true);
|
|
@@ -20373,6 +20509,7 @@ function ownEnumerableSandboxEntries(value, excludedKeys) {
|
|
|
20373
20509
|
if (value === null || value === void 0) throw new TypeError("Cannot convert undefined or null to object.");
|
|
20374
20510
|
let entries;
|
|
20375
20511
|
if (isGuestClosure(value)) entries = Object.entries(value.properties ?? {});
|
|
20512
|
+
else if (isSandboxRegex(value)) entries = Object.entries(getRegexProperties(value));
|
|
20376
20513
|
else if (isSandboxClosure(value) || isSandboxGenerator(value) || isSandboxMap(value) || isSandboxSet(value) || isSandboxPromise(value) || isSandboxRegex(value)) return [];
|
|
20377
20514
|
else entries = Object.entries(Object(value));
|
|
20378
20515
|
return excludedKeys === void 0 ? entries : entries.filter(([key]) => !excludedKeys.has(key));
|
|
@@ -20381,17 +20518,19 @@ function ownSandboxSymbolKeys(value) {
|
|
|
20381
20518
|
if (value === null || value === void 0) throw new TypeError("Cannot convert undefined or null to object.");
|
|
20382
20519
|
if (isGuestHostObject(value)) return [];
|
|
20383
20520
|
if (isSandboxClosure(value)) value = value.properties ?? {};
|
|
20521
|
+
else if (isSandboxRegex(value)) value = getRegexProperties(value);
|
|
20384
20522
|
else if (isSandboxGenerator(value) || isSandboxMap(value) || isSandboxSet(value) || isSandboxPromise(value) || isSandboxRegex(value)) return [];
|
|
20385
20523
|
return Object.getOwnPropertySymbols(Object(value)).filter((key) => !internalSymbols.has(key));
|
|
20386
20524
|
}
|
|
20387
20525
|
function ownEnumerableSandboxKeys(value, includeSymbols = false) {
|
|
20388
20526
|
if (includeSymbols) {
|
|
20389
|
-
const properties = isSandboxClosure(value) ? value.properties ?? {} : Object(value);
|
|
20527
|
+
const properties = isSandboxClosure(value) ? value.properties ?? {} : isSandboxRegex(value) ? getRegexProperties(value) : Object(value);
|
|
20390
20528
|
return [...ownEnumerableSandboxKeys(value), ...ownSandboxSymbolKeys(value).filter((key) => Object.getOwnPropertyDescriptor(properties, key)?.enumerable === true)];
|
|
20391
20529
|
}
|
|
20392
20530
|
if (isGuestHostObject(value)) return getHostObjectKeys(value);
|
|
20393
20531
|
if (value === null || value === void 0) throw new TypeError("Cannot convert undefined or null to object.");
|
|
20394
20532
|
if (isGuestClosure(value)) return Object.keys(value.properties ?? {});
|
|
20533
|
+
if (isSandboxRegex(value)) return Object.keys(getRegexProperties(value));
|
|
20395
20534
|
if (isSandboxClosure(value) || isSandboxGenerator(value) || isSandboxMap(value) || isSandboxSet(value) || isSandboxPromise(value) || isSandboxRegex(value)) return [];
|
|
20396
20535
|
return Object.keys(Object(value));
|
|
20397
20536
|
}
|
|
@@ -20483,6 +20622,28 @@ function createSandboxRegex(source, flags = "", lastIndex = 0, compilation) {
|
|
|
20483
20622
|
}
|
|
20484
20623
|
const pattern = parseRegex(source, flags, compilation, 7 + source.length + flags.length);
|
|
20485
20624
|
const regex = { kind: "regex", source, flags, lastIndex };
|
|
20625
|
+
const storage = /* @__PURE__ */ Object.create(null);
|
|
20626
|
+
Object.defineProperty(storage, "lastIndex", { value: lastIndex, writable: true });
|
|
20627
|
+
const syncCursor = () => {
|
|
20628
|
+
const descriptor = Object.getOwnPropertyDescriptor(regex, "lastIndex");
|
|
20629
|
+
Object.defineProperty(storage, "lastIndex", { value: descriptor.value, writable: descriptor.writable });
|
|
20630
|
+
};
|
|
20631
|
+
const properties = new Proxy(storage, {
|
|
20632
|
+
get: (target, key, receiver) => key === "lastIndex" ? regex.lastIndex : Reflect.get(target, key, receiver),
|
|
20633
|
+
set: (target, key, value, receiver) => key === "lastIndex" ? Reflect.set(regex, key, value) : Reflect.set(target, key, value, receiver),
|
|
20634
|
+
getOwnPropertyDescriptor(target, key) {
|
|
20635
|
+
if (key === "lastIndex") syncCursor();
|
|
20636
|
+
return Object.getOwnPropertyDescriptor(target, key);
|
|
20637
|
+
},
|
|
20638
|
+
defineProperty(target, key, descriptor) {
|
|
20639
|
+
if (key !== "lastIndex") return Reflect.defineProperty(target, key, descriptor);
|
|
20640
|
+
syncCursor();
|
|
20641
|
+
if (!Reflect.defineProperty(target, key, descriptor)) return false;
|
|
20642
|
+
const cursor = Object.getOwnPropertyDescriptor(target, key);
|
|
20643
|
+
return Reflect.defineProperty(regex, key, { value: cursor.value, writable: cursor.writable });
|
|
20644
|
+
}
|
|
20645
|
+
});
|
|
20646
|
+
regexGuestProperties.set(regex, properties);
|
|
20486
20647
|
Object.defineProperties(regex, {
|
|
20487
20648
|
[sandboxRegexBrand]: { value: true },
|
|
20488
20649
|
[sandboxRegexPattern]: { value: pattern }
|
|
@@ -20658,6 +20819,14 @@ function measureSandboxData(values, options = {}) {
|
|
|
20658
20819
|
usage += Math.max(6 + source.length + flags.length + compiled.units, staged - 1);
|
|
20659
20820
|
if (compiled.ticket !== void 0) options.compileTickets?.add(compiled.ticket);
|
|
20660
20821
|
visit(lastIndex, depth + 1);
|
|
20822
|
+
for (const key of Reflect.ownKeys(getRegexProperties(value))) {
|
|
20823
|
+
if (key === "lastIndex") continue;
|
|
20824
|
+
const descriptor = Object.getOwnPropertyDescriptor(getRegexProperties(value), key);
|
|
20825
|
+
usage += 1 + (typeof key === "string" ? key.length : 0);
|
|
20826
|
+
if (typeof key === "symbol") visit(key, depth + 1);
|
|
20827
|
+
if ("value" in descriptor) visit(descriptor.value, depth + 1);
|
|
20828
|
+
else for (const closure of retainedAccessorClosures(descriptor)) visit(closure, depth + 1);
|
|
20829
|
+
}
|
|
20661
20830
|
return;
|
|
20662
20831
|
}
|
|
20663
20832
|
if (isSandboxArguments(value)) {
|
|
@@ -20718,7 +20887,7 @@ function captureRegexData(value) {
|
|
|
20718
20887
|
"Invalid sandbox RegExp source or flags: expected own string data properties."
|
|
20719
20888
|
);
|
|
20720
20889
|
}
|
|
20721
|
-
const cursor = Object.getOwnPropertyDescriptor(value, "lastIndex");
|
|
20890
|
+
const cursor = Object.getOwnPropertyDescriptor(regexGuestProperties.get(value) ?? value, "lastIndex");
|
|
20722
20891
|
if (cursor === void 0 || !("value" in cursor)) {
|
|
20723
20892
|
throw new TypeError("Invalid sandbox RegExp lastIndex: expected an own data property.");
|
|
20724
20893
|
}
|
|
@@ -20747,6 +20916,18 @@ function copyToSandbox(value, state, path = "<root>", cloneSandboxCollections =
|
|
|
20747
20916
|
const copy = createSandboxRegex(value.source, value.flags, 0, state.compilation);
|
|
20748
20917
|
state.seen.set(value, copy);
|
|
20749
20918
|
if (!state.resetRegexLastIndex) copy.lastIndex = copyToSandbox(value.lastIndex, state, `${path}.lastIndex`, true, depth + 1);
|
|
20919
|
+
if (!state.structuredClone) {
|
|
20920
|
+
const properties = getRegexProperties(value);
|
|
20921
|
+
for (const key of Reflect.ownKeys(properties)) {
|
|
20922
|
+
const descriptor = Object.getOwnPropertyDescriptor(properties, key);
|
|
20923
|
+
if (!("value" in descriptor)) throw new TypeError("RegExp accessor properties cannot be copied as data.");
|
|
20924
|
+
Object.defineProperty(getRegexProperties(copy), key, {
|
|
20925
|
+
...descriptor,
|
|
20926
|
+
value: key === "lastIndex" && state.resetRegexLastIndex ? 0 : copyToSandbox(descriptor.value, state, `${path}.${String(key)}`, true, depth + 1)
|
|
20927
|
+
});
|
|
20928
|
+
}
|
|
20929
|
+
if (!Object.isExtensible(properties)) Object.preventExtensions(getRegexProperties(copy));
|
|
20930
|
+
}
|
|
20750
20931
|
return copy;
|
|
20751
20932
|
}
|
|
20752
20933
|
if (isSandboxClosure(value) || isSandboxGenerator(value) || isSandboxPromise(value)) {
|
|
@@ -20995,6 +21176,18 @@ function copyFromSandbox(value, state, path = "<root>", options, depth = 0) {
|
|
|
20995
21176
|
const regex = new RegExp(source, flags);
|
|
20996
21177
|
state.seen.set(value, regex);
|
|
20997
21178
|
Reflect.set(regex, "lastIndex", copyFromSandbox(lastIndex, state, `${path}.lastIndex`, options, depth + 1));
|
|
21179
|
+
const properties = regexGuestProperties.get(value);
|
|
21180
|
+
if (properties !== void 0) {
|
|
21181
|
+
for (const key of Reflect.ownKeys(properties)) {
|
|
21182
|
+
const descriptor = Object.getOwnPropertyDescriptor(properties, key);
|
|
21183
|
+
if (!("value" in descriptor)) throw new TypeError("RegExp accessor properties cannot be copied as data.");
|
|
21184
|
+
Object.defineProperty(regex, key, {
|
|
21185
|
+
...descriptor,
|
|
21186
|
+
value: copyFromSandbox(descriptor.value, state, `${path}.${String(key)}`, options, depth + 1)
|
|
21187
|
+
});
|
|
21188
|
+
}
|
|
21189
|
+
if (!Object.isExtensible(properties)) Object.preventExtensions(regex);
|
|
21190
|
+
}
|
|
20998
21191
|
guard.retainScratch();
|
|
20999
21192
|
return regex;
|
|
21000
21193
|
} finally {
|
|
@@ -33338,7 +33531,7 @@ function createReplayableRandom(options = {}) {
|
|
|
33338
33531
|
|
|
33339
33532
|
// packages/safe-js/src/realm.ts
|
|
33340
33533
|
import { AsyncLocalStorage as AsyncLocalStorage6 } from "node:async_hooks";
|
|
33341
|
-
import { types as
|
|
33534
|
+
import { types as types7 } from "node:util";
|
|
33342
33535
|
|
|
33343
33536
|
// packages/safe-js/src/interp/globals/console-json.ts
|
|
33344
33537
|
function createConsoleJsonGlobals(options) {
|
|
@@ -34017,7 +34210,7 @@ var RealmState = class {
|
|
|
34017
34210
|
throw new TypeError("Realm limits must be positive safe integers with supported names.");
|
|
34018
34211
|
this.limits[name] = Number(value);
|
|
34019
34212
|
}
|
|
34020
|
-
if (options.extensions !== void 0 && (!Array.isArray(options.extensions) ||
|
|
34213
|
+
if (options.extensions !== void 0 && (!Array.isArray(options.extensions) || types7.isProxy(options.extensions)))
|
|
34021
34214
|
throw new TypeError("Extensions must be a registration array.");
|
|
34022
34215
|
const registrations = options.extensions ?? [];
|
|
34023
34216
|
const extensions = [];
|
|
@@ -34252,7 +34445,7 @@ var RealmState = class {
|
|
|
34252
34445
|
return this.phase.run(phase, () => {
|
|
34253
34446
|
try {
|
|
34254
34447
|
const result = call();
|
|
34255
|
-
if (
|
|
34448
|
+
if (types7.isPromise(result) || phase.pending.size > 0 || phase.failure !== void 0) {
|
|
34256
34449
|
return Promise.resolve(result).then(
|
|
34257
34450
|
async (value) => {
|
|
34258
34451
|
await Promise.allSettled(phase.pending);
|
|
@@ -34321,7 +34514,7 @@ var RealmState = class {
|
|
|
34321
34514
|
},
|
|
34322
34515
|
read: (operation, validate) => {
|
|
34323
34516
|
const value = this.invokeHost(operation, operation);
|
|
34324
|
-
if (
|
|
34517
|
+
if (types7.isPromise(value)) {
|
|
34325
34518
|
void Promise.resolve(value).catch(() => void 0);
|
|
34326
34519
|
throw new TypeError("Live property operations must be synchronous.");
|
|
34327
34520
|
}
|
|
@@ -34329,7 +34522,7 @@ var RealmState = class {
|
|
|
34329
34522
|
},
|
|
34330
34523
|
write: (operation, value) => {
|
|
34331
34524
|
const result = this.invokeHost(operation, () => operation(this.exportValue(value)));
|
|
34332
|
-
if (
|
|
34525
|
+
if (types7.isPromise(result)) {
|
|
34333
34526
|
void Promise.resolve(result).catch(() => void 0);
|
|
34334
34527
|
throw new TypeError("Live property setters must be synchronous.");
|
|
34335
34528
|
}
|
|
@@ -34538,7 +34731,7 @@ var RealmState = class {
|
|
|
34538
34731
|
}
|
|
34539
34732
|
});
|
|
34540
34733
|
const output = getExtensionSetup(extension)(context);
|
|
34541
|
-
if (
|
|
34734
|
+
if (types7.isPromise(output)) {
|
|
34542
34735
|
void Promise.resolve(output).catch(() => void 0);
|
|
34543
34736
|
throw new TypeError("Extension setup must be synchronous.");
|
|
34544
34737
|
}
|
|
@@ -34730,7 +34923,7 @@ var RealmState = class {
|
|
|
34730
34923
|
};
|
|
34731
34924
|
function readModules(input) {
|
|
34732
34925
|
const entries = (value, label) => {
|
|
34733
|
-
if (
|
|
34926
|
+
if (types7.isMap(value) && !types7.isProxy(value)) {
|
|
34734
34927
|
const result = [...Map.prototype.entries.call(value)];
|
|
34735
34928
|
if (result.length > 4096 || result.some(([key]) => typeof key !== "string" || key.length === 0))
|
|
34736
34929
|
throw new TypeError(`${label} requires bounded string keys.`);
|
|
@@ -35945,7 +36138,6 @@ export {
|
|
|
35945
36138
|
parse,
|
|
35946
36139
|
parseModule,
|
|
35947
36140
|
hashSource,
|
|
35948
|
-
defineExtension,
|
|
35949
36141
|
noopOtelSink,
|
|
35950
36142
|
bindOtelSpan,
|
|
35951
36143
|
activateOtelSpan,
|
|
@@ -35954,6 +36146,7 @@ export {
|
|
|
35954
36146
|
safeAddEvent,
|
|
35955
36147
|
safeRecordException,
|
|
35956
36148
|
safeEndSpan,
|
|
36149
|
+
defineExtension,
|
|
35957
36150
|
encodeReplayData,
|
|
35958
36151
|
HostOperationResumePolicyError,
|
|
35959
36152
|
registerPendingHostCallPolicy,
|
|
@@ -35986,4 +36179,4 @@ export {
|
|
|
35986
36179
|
FileSnapshotBackend,
|
|
35987
36180
|
run
|
|
35988
36181
|
};
|
|
35989
|
-
//# sourceMappingURL=chunk-
|
|
36182
|
+
//# sourceMappingURL=chunk-XKCTB5FR.js.map
|