@poe-platform/safe-js 0.1.222 → 0.1.224

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.
@@ -138,6 +138,47 @@ function findSourceOffset(source, line, column) {
138
138
  return source.length;
139
139
  }
140
140
 
141
+ // packages/safe-js/src/interp/template-objects.ts
142
+ var realms = /* @__PURE__ */ new WeakMap();
143
+ var templateOrigins = /* @__PURE__ */ new WeakMap();
144
+ var templateRawArrays = /* @__PURE__ */ new WeakMap();
145
+ var templateCookedArrays = /* @__PURE__ */ new WeakMap();
146
+ function templateObject(node, budget) {
147
+ const cached = realms.get(budget)?.get(node);
148
+ if (cached !== void 0) return cached;
149
+ budget.allocateArrayLength(node.quasis.length);
150
+ const strings = node.quasis.map((quasi) => quasi.value.cooked === void 0 ? void 0 : budget.allocateString(quasi.value.cooked));
151
+ const raw = node.quasis.map((quasi) => budget.allocateString(quasi.value.raw));
152
+ Object.freeze(raw);
153
+ Object.defineProperty(strings, "raw", { value: raw });
154
+ Object.freeze(strings);
155
+ registerTemplateObject(node, strings, budget);
156
+ return strings;
157
+ }
158
+ function registerTemplateObject(node, value, budget) {
159
+ const raw = Object.getOwnPropertyDescriptor(value, "raw")?.value;
160
+ if (!Object.isFrozen(value) || !Array.isArray(raw) || !Object.isFrozen(raw) || value.length !== node.quasis.length || raw.length !== node.quasis.length || node.quasis.some((quasi, index) => Object.getOwnPropertyDescriptor(value, String(index))?.value !== quasi.value.cooked || Object.getOwnPropertyDescriptor(raw, String(index))?.value !== quasi.value.raw))
161
+ throw new TypeError("Invalid template object contents.");
162
+ let realm = realms.get(budget);
163
+ const existing = realm?.get(node);
164
+ if (existing !== void 0 && existing !== value) throw new TypeError("Conflicting template object identity.");
165
+ if (realm === void 0) {
166
+ realm = /* @__PURE__ */ new Map();
167
+ realms.set(budget, realm);
168
+ const retained = realm;
169
+ budget.setRetainedValues(realm, () => retained.values());
170
+ }
171
+ realm.set(node, value);
172
+ templateOrigins.set(value, node);
173
+ templateRawArrays.set(value, raw);
174
+ templateCookedArrays.set(raw, value);
175
+ }
176
+ function releaseTemplateObjects(budget) {
177
+ const realm = realms.get(budget);
178
+ if (realm !== void 0) budget.setRetainedValues(realm, void 0);
179
+ realms.delete(budget);
180
+ }
181
+
141
182
  // packages/safe-js/src/interp/budget.ts
142
183
  var REGEX_STEP_LIMIT = 2e3;
143
184
  var REGEX_COMPILE_LIMITS = Object.freeze({
@@ -391,6 +432,7 @@ var Budget = class {
391
432
  }
392
433
  reset() {
393
434
  if (this.compileUses !== 0) throw new SandboxError("reentry");
435
+ releaseTemplateObjects(this);
394
436
  this.compileGeneration += 1;
395
437
  this.defaultCompileOwner = void 0;
396
438
  this.provisionalScopes = 0;
@@ -6860,9 +6902,9 @@ function exportDate(value) {
6860
6902
  return new NativeDate(dateTime(value));
6861
6903
  }
6862
6904
  function dateDataProperties(value) {
6863
- const descriptors = Object.getOwnPropertyDescriptors(value);
6864
- return Reflect.ownKeys(descriptors).map((key) => {
6865
- const descriptor = Object.getOwnPropertyDescriptor(descriptors, key).value;
6905
+ const descriptors2 = Object.getOwnPropertyDescriptors(value);
6906
+ return Reflect.ownKeys(descriptors2).map((key) => {
6907
+ const descriptor = Object.getOwnPropertyDescriptor(descriptors2, key).value;
6866
6908
  if (!("value" in descriptor)) throw new TypeError("Date accessor properties cannot be copied as data.");
6867
6909
  return [key, descriptor];
6868
6910
  });
@@ -7159,9 +7201,9 @@ function primitiveReceiver(value, kind) {
7159
7201
  }
7160
7202
  function boxedDataProperties(value, includeSymbols = false) {
7161
7203
  const primitive = nativeBoxedValue(value);
7162
- const descriptors = Object.getOwnPropertyDescriptors(value);
7163
- const keys = includeSymbols ? Reflect.ownKeys(descriptors) : Object.keys(descriptors);
7164
- return keys.map((key) => [key, Object.getOwnPropertyDescriptor(descriptors, key).value]).filter(([key]) => {
7204
+ const descriptors2 = Object.getOwnPropertyDescriptors(value);
7205
+ const keys = includeSymbols ? Reflect.ownKeys(descriptors2) : Object.keys(descriptors2);
7206
+ return keys.map((key) => [key, Object.getOwnPropertyDescriptor(descriptors2, key).value]).filter(([key]) => {
7165
7207
  if (typeof key === "symbol") return true;
7166
7208
  if (typeof primitive !== "string") return true;
7167
7209
  if (key === "length") return false;
@@ -7910,10 +7952,10 @@ function getGeneratorOrigin(value) {
7910
7952
 
7911
7953
  // packages/safe-js/src/interp/intrinsics.ts
7912
7954
  var identities = /* @__PURE__ */ new WeakMap();
7913
- var realms = /* @__PURE__ */ new WeakMap();
7955
+ var realms2 = /* @__PURE__ */ new WeakMap();
7914
7956
  function registerBuiltinIdentities(budget, bindings) {
7915
- let realm = realms.get(budget);
7916
- if (realm === void 0) realms.set(budget, realm = /* @__PURE__ */ new Map());
7957
+ let realm = realms2.get(budget);
7958
+ if (realm === void 0) realms2.set(budget, realm = /* @__PURE__ */ new Map());
7917
7959
  const pending = Object.entries(bindings).map(([name, value]) => [[name], value]);
7918
7960
  const visited = /* @__PURE__ */ new WeakSet();
7919
7961
  for (let index = 0; index < pending.length; index++) {
@@ -7948,15 +7990,15 @@ function getIntrinsicIdentity(value) {
7948
7990
  return identities.get(value);
7949
7991
  }
7950
7992
  function resolveIntrinsicIdentity(budget, id) {
7951
- const value = realms.get(budget)?.get(id);
7993
+ const value = realms2.get(budget)?.get(id);
7952
7994
  if (value === void 0) throw new TypeError(`Unknown intrinsic identity: ${id}`);
7953
7995
  return value;
7954
7996
  }
7955
7997
  function listIntrinsicIdentities(budget) {
7956
- return [...realms.get(budget)?.keys() ?? []];
7998
+ return [...realms2.get(budget)?.keys() ?? []];
7957
7999
  }
7958
8000
  function releaseIntrinsicIdentities(budget) {
7959
- realms.delete(budget);
8001
+ realms2.delete(budget);
7960
8002
  }
7961
8003
 
7962
8004
  // packages/safe-js/src/interp/object-model.ts
@@ -8074,23 +8116,24 @@ function registerIntrinsicPrototype(budget, prototype, constructor) {
8074
8116
  const unchanged = (before, after) => before !== void 0 && after !== void 0 && Object.is(before.value, after.value) && before.get === after.get && before.set === after.set && before.writable === after.writable && before.configurable === after.configurable && before.enumerable === after.enumerable;
8075
8117
  intrinsicConstructors.set(
8076
8118
  constructor,
8077
- () => records.every(({ target, value, descriptors, prototype: parent, explicit, extensible }) => {
8119
+ () => records.every(({ target, value, descriptors: descriptors2, prototype: parent, explicit, extensible }) => {
8078
8120
  const current = Object.getOwnPropertyDescriptors(value);
8079
- return getSandboxPrototype(target) === parent && Object.isExtensible(value) === extensible && hasExplicitSandboxPrototype(target) === explicit && Reflect.ownKeys(current).length === descriptors.size && Reflect.ownKeys(value).every((key) => unchanged(descriptors.get(key), Object.getOwnPropertyDescriptor(value, key)));
8121
+ return getSandboxPrototype(target) === parent && Object.isExtensible(value) === extensible && hasExplicitSandboxPrototype(target) === explicit && Reflect.ownKeys(current).length === descriptors2.size && Reflect.ownKeys(value).every((key) => unchanged(descriptors2.get(key), Object.getOwnPropertyDescriptor(value, key)));
8080
8122
  })
8081
8123
  );
8082
8124
  budget.setRetainedValues(
8083
8125
  prototype,
8084
- () => records.flatMap(({ target, value, descriptors, prototype: parent }) => [
8126
+ () => records.flatMap(({ target, value, descriptors: descriptors2, prototype: parent }) => [
8085
8127
  ...getSandboxPrototype(target) === parent ? [] : [getSandboxPrototype(target)],
8086
8128
  ...Reflect.ownKeys(value).flatMap((key) => {
8087
8129
  const descriptor = Object.getOwnPropertyDescriptor(value, key);
8088
- return unchanged(descriptors.get(key), descriptor) ? [] : [key, descriptor.value, ...retainedAccessorClosures(descriptor)];
8130
+ return unchanged(descriptors2.get(key), descriptor) ? [] : [key, descriptor.value, ...retainedAccessorClosures(descriptor)];
8089
8131
  })
8090
8132
  ])
8091
8133
  );
8092
8134
  }
8093
8135
  function releaseObjectPrototype(budget) {
8136
+ releaseTemplateObjects(budget);
8094
8137
  releaseIntrinsicIdentities(budget);
8095
8138
  for (const prototype of intrinsicPrototypeRoots.get(budget) ?? []) budget.setRetainedValues(prototype, void 0);
8096
8139
  intrinsicPrototypeRoots.delete(budget);
@@ -8538,7 +8581,11 @@ function captureGuestHeapNode(value, encode) {
8538
8581
  ...value.state !== "suspended" || origin2.expressionStates === void 0 ? {} : {
8539
8582
  expressionStates: Object.fromEntries([...origin2.expressionStates].map(([id, expression]) => [
8540
8583
  String(id),
8541
- expression.kind === "binary" ? { kind: "binary", left: encode(expression.left) } : expression.kind === "template" ? { ...expression } : expression.kind === "object" ? {
8584
+ expression.kind === "binary" ? { kind: "binary", left: encode(expression.left) } : expression.kind === "member" ? {
8585
+ kind: "member",
8586
+ object: encode(expression.object),
8587
+ ...Object.hasOwn(expression, "superReceiver") ? { superReceiver: encode(expression.superReceiver) } : {}
8588
+ } : expression.kind === "template" ? { ...expression } : expression.kind === "object" ? {
8542
8589
  kind: "object",
8543
8590
  value: encode(expression.value),
8544
8591
  index: expression.index,
@@ -8559,7 +8606,16 @@ function captureGuestHeapNode(value, encode) {
8559
8606
  if (Array.isArray(value) && (!Object.isExtensible(value) || hasExplicitSandboxPrototype(value) || Reflect.ownKeys(value).some((key) => {
8560
8607
  const descriptor = Object.getOwnPropertyDescriptor(value, key);
8561
8608
  return key === "length" ? descriptor.writable !== true : !("value" in descriptor) || !descriptor.enumerable || !descriptor.configurable || !descriptor.writable;
8562
- }))) return { kind: "guest-array", state: captureObjectState(value, encode) };
8609
+ }))) {
8610
+ const templateNodeId = templateOrigins.get(value)?.nodeId;
8611
+ const templateOwner = templateCookedArrays.get(value);
8612
+ return {
8613
+ kind: "guest-array",
8614
+ state: captureObjectState(value, encode),
8615
+ ...templateNodeId === void 0 ? {} : { templateNodeId },
8616
+ ...templateOwner === void 0 ? {} : { templateOwner: encode(templateOwner) }
8617
+ };
8618
+ }
8563
8619
  if (isLiveCapability(value) || isSandboxClosure(value) || isSandboxBox(value) || isSandboxDate(value) || isSandboxRegex(value) || isSandboxMap(value) || isSandboxSet(value) || isSandboxPromise(value) || isSandboxGenerator(value) || isSandboxArguments(value) || isSandboxCollectionIterator(value) || isSandboxRegExpIterator(value)) return void 0;
8564
8620
  const prototype = Object.getPrototypeOf(value);
8565
8621
  if ((prototype === null || prototype === Object.prototype) && hasGuestObjectState(value))
@@ -13517,11 +13573,11 @@ function createObjectArrayGlobals(options) {
13517
13573
  getOwnPropertyDescriptors: createSandboxClosure({
13518
13574
  sandbox: true,
13519
13575
  call: ([value]) => {
13520
- const descriptors = /* @__PURE__ */ Object.create(null);
13576
+ const descriptors2 = /* @__PURE__ */ Object.create(null);
13521
13577
  const properties = objectProperties(value);
13522
13578
  for (const key of [...Object.getOwnPropertyNames(properties), ...ownSandboxSymbolKeys(value)])
13523
- defineOwnDataProperty(descriptors, key, exposePropertyDescriptor(Object.getOwnPropertyDescriptor(properties, key)));
13524
- return allocateProducedSandboxValue(descriptors, options.budget);
13579
+ defineOwnDataProperty(descriptors2, key, exposePropertyDescriptor(Object.getOwnPropertyDescriptor(properties, key)));
13580
+ return allocateProducedSandboxValue(descriptors2, options.budget);
13525
13581
  },
13526
13582
  name: "getOwnPropertyDescriptors"
13527
13583
  }),
@@ -13552,8 +13608,8 @@ function createObjectArrayGlobals(options) {
13552
13608
  }),
13553
13609
  defineProperties: createSandboxClosure({
13554
13610
  sandbox: true,
13555
- call: async ([value, descriptors], context) => {
13556
- await definePropertiesFromObject(value, descriptors, options.budget, context);
13611
+ call: async ([value, descriptors2], context) => {
13612
+ await definePropertiesFromObject(value, descriptors2, options.budget, context);
13557
13613
  return value;
13558
13614
  },
13559
13615
  name: "defineProperties"
@@ -13582,12 +13638,12 @@ function createObjectArrayGlobals(options) {
13582
13638
  }),
13583
13639
  create: createSandboxClosure({
13584
13640
  sandbox: true,
13585
- call: async ([prototype, descriptors], context) => {
13641
+ call: async ([prototype, descriptors2], context) => {
13586
13642
  if (prototype !== null) objectProperties(prototype);
13587
13643
  const value = /* @__PURE__ */ Object.create(null);
13588
13644
  setSandboxPrototype(value, prototype, options.budget);
13589
- if (descriptors !== void 0) {
13590
- await definePropertiesFromObject(value, descriptors, options.budget, context);
13645
+ if (descriptors2 !== void 0) {
13646
+ await definePropertiesFromObject(value, descriptors2, options.budget, context);
13591
13647
  }
13592
13648
  return allocateProducedSandboxValue(value, options.budget);
13593
13649
  },
@@ -13936,19 +13992,19 @@ async function propertyDescriptor(input, budget, context) {
13936
13992
  release();
13937
13993
  }
13938
13994
  }
13939
- async function definePropertiesFromObject(target, descriptors, budget, context) {
13995
+ async function definePropertiesFromObject(target, descriptors2, budget, context) {
13940
13996
  objectProperties(target, true);
13941
13997
  const properties = [];
13942
13998
  const release = retainValues(budget, () => [
13943
13999
  target,
13944
- descriptors,
14000
+ descriptors2,
13945
14001
  properties,
13946
14002
  ...properties.flatMap(([, descriptor]) => retainedAccessorClosures(descriptor))
13947
14003
  ]);
13948
14004
  try {
13949
- for (const key of ownEnumerableSandboxKeys(descriptors, true)) {
13950
- if (!hasOwnSandboxProperty(descriptors, key, true)) continue;
13951
- const descriptor = await (context?.getProperty !== void 0 ? context.getProperty(descriptors, key) : getSandboxDataProperty(descriptors, key, budget));
14005
+ for (const key of ownEnumerableSandboxKeys(descriptors2, true)) {
14006
+ if (!hasOwnSandboxProperty(descriptors2, key, true)) continue;
14007
+ const descriptor = await (context?.getProperty !== void 0 ? context.getProperty(descriptors2, key) : getSandboxDataProperty(descriptors2, key, budget));
13952
14008
  properties.push([key, await propertyDescriptor(descriptor, budget, context)]);
13953
14009
  }
13954
14010
  for (const [key, descriptor] of properties) defineDataProperty(target, key, descriptor, budget);
@@ -16179,7 +16235,6 @@ function relativeIndex(value, length, fallback) {
16179
16235
  }
16180
16236
 
16181
16237
  // packages/safe-js/src/interp/interpreter.ts
16182
- var taggedTemplateRawArrays = /* @__PURE__ */ new WeakMap();
16183
16238
  var dispatchTable = {
16184
16239
  ArrayExpression: evaluateArrayExpression,
16185
16240
  AssignmentExpression: evaluateAssignmentExpression,
@@ -16654,7 +16709,7 @@ async function evaluateTaggedTemplateExpression(node, context) {
16654
16709
  hasValue: true,
16655
16710
  value: await invokeSandboxClosure(
16656
16711
  tag2,
16657
- [createTaggedTemplateStrings(node.quasi, context), ...values.value],
16712
+ [templateObject(node.quasi, context.budget), ...values.value],
16658
16713
  context,
16659
16714
  [...context.callStack, formatStackFrame(node, tag2.name)],
16660
16715
  node.span,
@@ -16679,26 +16734,6 @@ async function evaluateTaggedTemplateExpression(node, context) {
16679
16734
  const tag = await evaluateNode(node.tag, context);
16680
16735
  return tag.kind === "normal" ? invokeTag(tag.value, void 0) : tag;
16681
16736
  }
16682
- function createTaggedTemplateStrings(node, context) {
16683
- context.budget.allocateArrayLength(node.quasis.length);
16684
- const strings = node.quasis.map(
16685
- (quasi) => quasi.value.cooked === void 0 ? void 0 : context.budget.allocateString(quasi.value.cooked)
16686
- );
16687
- context.budget.allocateArrayLength(node.quasis.length);
16688
- const raw = node.quasis.map(
16689
- (quasi) => context.budget.allocateString(quasi.value.raw)
16690
- );
16691
- Object.defineProperty(strings, "raw", {
16692
- configurable: false,
16693
- enumerable: false,
16694
- value: raw,
16695
- writable: false
16696
- });
16697
- taggedTemplateRawArrays.set(strings, raw);
16698
- Object.freeze(raw);
16699
- Object.freeze(strings);
16700
- return strings;
16701
- }
16702
16737
  async function evaluateArrowFunction(node, context) {
16703
16738
  return evaluateArrowFunctionExpression(node, context, evaluateNode);
16704
16739
  }
@@ -18197,13 +18232,24 @@ function attachFatalSandboxErrorContext(error, node, stackFrames) {
18197
18232
  replaceErrorStack(error, stackFrames);
18198
18233
  }
18199
18234
  async function evaluateMemberAccess(node, context, consume) {
18200
- const superReceiver = node.object.type === "Super" ? { value: context.scope.lookup("this") } : void 0;
18201
- const object = await evaluateNode(node.object, context);
18235
+ const restored = context.generatorResume === void 0 || node.nodeId === void 0 ? void 0 : context.restoredGeneratorExpressionStates?.get(node.nodeId);
18236
+ if (restored !== void 0 && restored.kind !== "member") throw new TypeError("Invalid member continuation.");
18237
+ const thisBinding = node.object.type === "Super" ? context.scope.lookup("this") : void 0;
18238
+ const superReceiver = restored?.kind === "member" && Object.hasOwn(restored, "superReceiver") ? { value: restored.superReceiver } : thisBinding === void 0 ? void 0 : { value: thisBinding.found ? thisBinding.value : void 0 };
18239
+ const object = restored?.kind === "member" ? { kind: "normal", value: restored.object } : await evaluateNode(node.object, context);
18202
18240
  if (object.kind !== "normal") return object;
18203
18241
  if ((object.value === null || object.value === void 0) && node.optional) {
18204
18242
  return consume({ kind: "nullish" });
18205
18243
  }
18206
18244
  let property;
18245
+ if (node.computed && context.generatorYield !== void 0 && node.nodeId !== void 0) {
18246
+ const state = {
18247
+ kind: "member",
18248
+ object: object.value,
18249
+ ...superReceiver === void 0 ? {} : { superReceiver: superReceiver.value }
18250
+ };
18251
+ context = { ...context, generatorExpressionStates: new Map([...context.generatorExpressionStates ?? [], [node.nodeId, state]]) };
18252
+ }
18207
18253
  const release = retainValues(context.budget, () => [object.value, property]);
18208
18254
  try {
18209
18255
  const result = node.computed ? await evaluateNode(node.property, context) : { kind: "normal", value: getStaticPropertyName2(node.property) };
@@ -18213,7 +18259,7 @@ async function evaluateMemberAccess(node, context, consume) {
18213
18259
  kind: "resolved",
18214
18260
  object: object.value,
18215
18261
  property,
18216
- ...superReceiver === void 0 ? {} : { superReceiver: { value: superReceiver.value.found ? superReceiver.value.value : void 0 } }
18262
+ ...superReceiver === void 0 ? {} : { superReceiver }
18217
18263
  });
18218
18264
  } finally {
18219
18265
  release();
@@ -18898,8 +18944,8 @@ function getMemberValue(target, property, context) {
18898
18944
  }
18899
18945
  function getArrayMemberValue(target, property, context) {
18900
18946
  if (hasExplicitSandboxPrototype(target)) return void 0;
18901
- if (property === "raw" && taggedTemplateRawArrays.has(target)) {
18902
- return taggedTemplateRawArrays.get(target);
18947
+ if (property === "raw" && templateRawArrays.has(target)) {
18948
+ return templateRawArrays.get(target);
18903
18949
  }
18904
18950
  return getArrayMember(target, property, createArrayMethodOptions(context));
18905
18951
  }
@@ -22350,7 +22396,10 @@ function validateGuestHeapNode(raw, heap, maxArrayLength = 4294967295) {
22350
22396
  if (typeof node.id !== "string" || !intrinsicCatalogue().has(node.id)) throw new TypeError("Unknown intrinsic identity.");
22351
22397
  if (Object.hasOwn(node, "state")) state(node.state);
22352
22398
  } else if (node.kind === "guest-object" || node.kind === "guest-array") {
22353
- fields(node, ["kind", "state"]);
22399
+ fields(node, ["kind", "state"], node.kind === "guest-array" ? ["templateNodeId", "templateOwner"] : []);
22400
+ if (Object.hasOwn(node, "templateOwner")) reference(node.templateOwner, ["guest-array"]);
22401
+ if (Object.hasOwn(node, "templateNodeId") && integer(node.templateNodeId) < 1)
22402
+ throw new TypeError("Invalid template source identity.");
22354
22403
  state(node.state);
22355
22404
  if (node.kind === "guest-array") {
22356
22405
  const properties = array(record2(record2(node.state).properties).properties).map((entry) => array(entry));
@@ -22396,6 +22445,8 @@ function validateGuestHeapNode(raw, heap, maxArrayLength = 4294967295) {
22396
22445
  const expression = record2(raw2);
22397
22446
  if (expression.kind === "binary") {
22398
22447
  fields(expression, ["kind", "left"]);
22448
+ } else if (expression.kind === "member") {
22449
+ fields(expression, ["kind", "object"], ["superReceiver"]);
22399
22450
  } else if (expression.kind === "template") {
22400
22451
  fields(expression, ["kind", "prefix", "index"]);
22401
22452
  integer(expression.index);
@@ -22571,7 +22622,7 @@ function validateGuestFunctionAst(record3, origin) {
22571
22622
  pending.push({
22572
22623
  value,
22573
22624
  blocks,
22574
- expressions: node.type === "BinaryExpression" && key === "right" && typeof node.nodeId === "number" ? new Map([...frame.expressions, [node.nodeId, { kind: "binary" }]]) : frame.expressions,
22625
+ expressions: node.type === "BinaryExpression" && key === "right" && typeof node.nodeId === "number" ? new Map([...frame.expressions, [node.nodeId, { kind: "binary" }]]) : node.type === "MemberExpression" && node.computed === true && key === "property" && typeof node.nodeId === "number" ? new Map([...frame.expressions, [node.nodeId, { kind: "member", superReceiver: node.object.type === "Super" }]]) : frame.expressions,
22575
22626
  finalizers: node.type === "TryStatement" && key === "finalizer" && typeof node.nodeId === "number" ? /* @__PURE__ */ new Set([...frame.finalizers, node.nodeId]) : frame.finalizers
22576
22627
  });
22577
22628
  }
@@ -22597,11 +22648,66 @@ function validateGuestFunctionAst(record3, origin) {
22597
22648
  for (const [id, expression] of expressions) {
22598
22649
  const expected = yieldExpressions?.get(Number(id));
22599
22650
  const compatibleKind = expected?.kind === expression.kind || expected?.kind === "call" && expected.member === true && expression.kind === "array-call";
22600
- if (expected === void 0 || !compatibleKind || expected.kind !== "binary" && expected.index !== expression.index || expected.kind === "object" && expected.key !== Object.hasOwn(expression, "key"))
22651
+ if (expected === void 0 || !compatibleKind || expected.kind !== "binary" && expected.kind !== "member" && expected.index !== expression.index || expected.kind === "member" && expected.superReceiver !== Object.hasOwn(expression, "superReceiver") || expected.kind === "object" && expected.key !== Object.hasOwn(expression, "key"))
22601
22652
  throw new TypeError("Invalid generator AST identity: unrelated expression continuation");
22602
22653
  }
22603
22654
  }
22604
22655
 
22656
+ // packages/safe-js/src/snapshot/template-validation.ts
22657
+ function validateTemplateObjects(heap, nodes) {
22658
+ const sites = /* @__PURE__ */ new Map();
22659
+ for (const node of nodes) {
22660
+ if (node.type === "TaggedTemplateExpression" && node.quasi.nodeId !== void 0)
22661
+ sites.set(node.quasi.nodeId, node.quasi);
22662
+ }
22663
+ const seen = /* @__PURE__ */ new Set();
22664
+ const rawOwners = /* @__PURE__ */ new Map();
22665
+ for (const raw of Object.values(heap)) {
22666
+ const entry = raw;
22667
+ if (entry.kind !== "guest-array" || entry.templateNodeId === void 0) continue;
22668
+ const node = sites.get(entry.templateNodeId);
22669
+ if (node === void 0 || seen.has(entry.templateNodeId)) throw new TypeError("Invalid or duplicate template source identity.");
22670
+ seen.add(entry.templateNodeId);
22671
+ const cooked = descriptors(entry.state);
22672
+ const rawReference = cooked.get("raw")?.value;
22673
+ const rawArray = rawReference?.kind === "ref" ? heap[String(rawReference.id)] : void 0;
22674
+ if (rawArray?.kind !== "guest-array") throw new TypeError("Invalid template raw array.");
22675
+ if (rawOwners.has(rawArray) && rawOwners.get(rawArray) !== raw) throw new TypeError("Conflicting template raw identity.");
22676
+ rawOwners.set(rawArray, raw);
22677
+ checkArray(cooked, node.quasis.map((quasi) => quasi.value.cooked), true);
22678
+ checkArray(descriptors(rawArray.state), node.quasis.map((quasi) => quasi.value.raw), false);
22679
+ }
22680
+ for (const [raw, owner] of rawOwners) {
22681
+ const reference = raw.templateOwner;
22682
+ if (reference === void 0 || heap[String(reference.id)] !== owner)
22683
+ throw new TypeError("Missing or invalid template owner identity.");
22684
+ }
22685
+ for (const raw of Object.values(heap)) {
22686
+ const entry = raw;
22687
+ if (entry.templateOwner !== void 0 && rawOwners.get(raw) !== heap[String(entry.templateOwner.id)])
22688
+ throw new TypeError("Invalid template owner identity.");
22689
+ }
22690
+ }
22691
+ function descriptors(raw) {
22692
+ const state = raw;
22693
+ if (Object.hasOwn(state, "prototype") || state.properties.extensible !== false)
22694
+ throw new TypeError("Invalid template object state.");
22695
+ return new Map(state.properties.properties);
22696
+ }
22697
+ function checkArray(properties, values, cooked) {
22698
+ if (properties.size !== values.length + (cooked ? 2 : 1)) throw new TypeError("Invalid template property count.");
22699
+ const expected = new Map(values.map((value, index) => [String(index), value]));
22700
+ expected.set("length", values.length);
22701
+ if (cooked) expected.set("raw", properties.get("raw")?.value);
22702
+ for (const [key, value] of expected) {
22703
+ const descriptor = properties.get(key);
22704
+ const actual = descriptor?.value;
22705
+ const equal = value === void 0 ? actual !== null && typeof actual === "object" && actual.kind === "undefined" : actual === value;
22706
+ if (descriptor?.kind !== "data" || descriptor.configurable !== false || descriptor.writable !== false || descriptor.enumerable !== (key !== "length" && key !== "raw") || !equal)
22707
+ throw new TypeError("Invalid template property descriptor or contents.");
22708
+ }
22709
+ }
22710
+
22605
22711
  // packages/safe-js/src/snapshot/validation.ts
22606
22712
  var DEFAULT_MAX_DEPTH = MAX_DATA_DEPTH;
22607
22713
  var DEFAULT_MAX_ENTRIES = 1e5;
@@ -23873,8 +23979,8 @@ function measureSandboxData(values, options = {}) {
23873
23979
  seen.add(value);
23874
23980
  usage += 1;
23875
23981
  if (!isGuestHostObject(value)) {
23876
- const descriptors2 = Object.getOwnPropertySymbols(value).filter((key) => !internalSymbols.has(key)).map((key) => [key, Object.getOwnPropertyDescriptor(value, key)]);
23877
- for (const [key, descriptor] of descriptors2) {
23982
+ const descriptors3 = Object.getOwnPropertySymbols(value).filter((key) => !internalSymbols.has(key)).map((key) => [key, Object.getOwnPropertyDescriptor(value, key)]);
23983
+ for (const [key, descriptor] of descriptors3) {
23878
23984
  usage += 1;
23879
23985
  visit(key, depth + 1);
23880
23986
  if ("value" in descriptor) visit(descriptor.value, depth + 1);
@@ -24010,16 +24116,16 @@ function measureSandboxData(values, options = {}) {
24010
24116
  }
24011
24117
  return;
24012
24118
  }
24013
- const descriptors = Object.getOwnPropertyDescriptors(value);
24014
- const keys = Object.keys(descriptors);
24119
+ const descriptors2 = Object.getOwnPropertyDescriptors(value);
24120
+ const keys = Object.keys(descriptors2);
24015
24121
  const includeNonEnumerable = isSandboxDate(value) || hasManagedDescriptors(value);
24016
24122
  let entryCount = 0;
24017
24123
  for (const key of keys) {
24018
- if (descriptors[key].enumerable || includeNonEnumerable) entryCount += 1;
24124
+ if (descriptors2[key].enumerable || includeNonEnumerable) entryCount += 1;
24019
24125
  }
24020
24126
  usage += entryCount;
24021
24127
  for (const key of keys) {
24022
- const descriptor = descriptors[key];
24128
+ const descriptor = descriptors2[key];
24023
24129
  if (!descriptor.enumerable && !includeNonEnumerable) continue;
24024
24130
  usage += key.length;
24025
24131
  if ("value" in descriptor) visit(descriptor.value, depth + 1);
@@ -24627,11 +24733,11 @@ function defineOwnDataProperty(target, key, value) {
24627
24733
  });
24628
24734
  }
24629
24735
  function getEnumerableObjectEntries(value, path) {
24630
- const descriptors = Object.getOwnPropertyDescriptors(value);
24736
+ const descriptors2 = Object.getOwnPropertyDescriptors(value);
24631
24737
  const entries = [];
24632
- for (const key of Reflect.ownKeys(descriptors)) {
24738
+ for (const key of Reflect.ownKeys(descriptors2)) {
24633
24739
  if (typeof key === "symbol" && internalSymbols.has(key)) continue;
24634
- const descriptor = Object.getOwnPropertyDescriptor(descriptors, key).value;
24740
+ const descriptor = Object.getOwnPropertyDescriptor(descriptors2, key).value;
24635
24741
  if (!descriptor.enumerable) {
24636
24742
  continue;
24637
24743
  }
@@ -24646,11 +24752,11 @@ function getEnumerableObjectEntries(value, path) {
24646
24752
  return entries;
24647
24753
  }
24648
24754
  function getEnumerableArrayEntries(value, path) {
24649
- const descriptors = Object.getOwnPropertyDescriptors(value);
24755
+ const descriptors2 = Object.getOwnPropertyDescriptors(value);
24650
24756
  const entries = [];
24651
- for (const key of Reflect.ownKeys(descriptors)) {
24757
+ for (const key of Reflect.ownKeys(descriptors2)) {
24652
24758
  if (typeof key === "symbol" && internalSymbols.has(key)) continue;
24653
- const descriptor = Object.getOwnPropertyDescriptor(descriptors, key).value;
24759
+ const descriptor = Object.getOwnPropertyDescriptor(descriptors2, key).value;
24654
24760
  if (key === "length" || !descriptor.enumerable) {
24655
24761
  continue;
24656
24762
  }
@@ -25312,9 +25418,9 @@ function normalize(value, seen) {
25312
25418
  return normalized2;
25313
25419
  }
25314
25420
  const normalized = /* @__PURE__ */ Object.create(null);
25315
- const descriptors = Object.getOwnPropertyDescriptors(value);
25316
- for (const key of Object.keys(descriptors).sort()) {
25317
- const descriptor = descriptors[key];
25421
+ const descriptors2 = Object.getOwnPropertyDescriptors(value);
25422
+ for (const key of Object.keys(descriptors2).sort()) {
25423
+ const descriptor = descriptors2[key];
25318
25424
  if (!descriptor.enumerable) continue;
25319
25425
  if (!("value" in descriptor)) {
25320
25426
  throw new TypeError("Host call arguments cannot contain accessor properties.");
@@ -25556,7 +25662,7 @@ function restore(snapshot, options, owner) {
25556
25662
  throw new SnapshotMismatchError(snapshot.sourceHash, currentSourceHash);
25557
25663
  }
25558
25664
  if (snapshot.heap !== void 0 && typeof snapshot.heap === "object" && snapshot.heap !== null) {
25559
- const closures = Object.entries(snapshot.heap).filter(([, value]) => value !== null && typeof value === "object" && ["guest-function", "guest-generator"].includes(String(value.kind)));
25665
+ const closures = Object.entries(snapshot.heap).filter(([, value]) => value !== null && typeof value === "object" && (["guest-function", "guest-generator"].includes(String(value.kind)) || value.templateNodeId !== void 0));
25560
25666
  if (closures.length > 0) {
25561
25667
  const functions = /* @__PURE__ */ new Map();
25562
25668
  const pending = [parseModule(options.source, "<input>", owner)];
@@ -25564,13 +25670,14 @@ function restore(snapshot, options, owner) {
25564
25670
  const value = pending.pop();
25565
25671
  if (value === null || typeof value !== "object") continue;
25566
25672
  const node = value;
25567
- if (["ArrowFunctionExpression", "FunctionExpression", "FunctionDeclaration"].includes(String(node.type)) && typeof node.nodeId === "number") {
25673
+ if (typeof node.nodeId === "number") {
25568
25674
  functions.set(node.nodeId, node);
25569
25675
  }
25570
25676
  for (const entry of Object.values(node)) pending.push(entry);
25571
25677
  }
25572
25678
  for (const [id, value] of closures) {
25573
25679
  const record3 = value;
25680
+ if (record3.kind === "guest-array") continue;
25574
25681
  const origin = functions.get(record3.astNodeId);
25575
25682
  try {
25576
25683
  validateGuestFunctionAst(record3, origin);
@@ -25578,6 +25685,11 @@ function restore(snapshot, options, owner) {
25578
25685
  throw new SnapshotValidationError("invalidValue", `$.heap[${JSON.stringify(id)}].astNodeId`, error instanceof Error ? error.message : String(error));
25579
25686
  }
25580
25687
  }
25688
+ try {
25689
+ validateTemplateObjects(snapshot.heap, functions.values());
25690
+ } catch (error) {
25691
+ throw new SnapshotValidationError("invalidValue", "$.heap", String(error));
25692
+ }
25581
25693
  }
25582
25694
  }
25583
25695
  return snapshot;
@@ -38782,4 +38894,4 @@ export {
38782
38894
  FileSnapshotBackend,
38783
38895
  run
38784
38896
  };
38785
- //# sourceMappingURL=chunk-M7KI5UI3.js.map
38897
+ //# sourceMappingURL=chunk-DQY3GFKQ.js.map