@poe-platform/safe-js 0.1.221 → 0.1.223

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.
@@ -27,7 +27,7 @@ import {
27
27
  validateMigrationSemantics,
28
28
  validateSnapshotData,
29
29
  validateSnapshotMigration
30
- } from "./chunk-7DK7CIUK.js";
30
+ } from "./chunk-PEHO3DVD.js";
31
31
 
32
32
  // packages/safe-js/src/migrate.ts
33
33
  import { createHash } from "node:crypto";
@@ -8249,4 +8249,4 @@ export {
8249
8249
  parseMcpConfig,
8250
8250
  makeMcpModule
8251
8251
  };
8252
- //# sourceMappingURL=chunk-VVZQNTZ6.js.map
8252
+ //# sourceMappingURL=chunk-JJKJAB53.js.map
@@ -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);
@@ -8555,6 +8598,20 @@ function captureGuestHeapNode(value, encode) {
8555
8598
  }
8556
8599
  const origin = getClosureOrigin(value);
8557
8600
  if (origin === void 0) {
8601
+ if (Array.isArray(value) && Object.values(Object.getOwnPropertyDescriptors(value)).some((descriptor) => !("value" in descriptor) && retainedAccessorClosures(descriptor).length !== Number(descriptor.get !== void 0) + Number(descriptor.set !== void 0))) return void 0;
8602
+ if (Array.isArray(value) && (!Object.isExtensible(value) || hasExplicitSandboxPrototype(value) || Reflect.ownKeys(value).some((key) => {
8603
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
8604
+ return key === "length" ? descriptor.writable !== true : !("value" in descriptor) || !descriptor.enumerable || !descriptor.configurable || !descriptor.writable;
8605
+ }))) {
8606
+ const templateNodeId = templateOrigins.get(value)?.nodeId;
8607
+ const templateOwner = templateCookedArrays.get(value);
8608
+ return {
8609
+ kind: "guest-array",
8610
+ state: captureObjectState(value, encode),
8611
+ ...templateNodeId === void 0 ? {} : { templateNodeId },
8612
+ ...templateOwner === void 0 ? {} : { templateOwner: encode(templateOwner) }
8613
+ };
8614
+ }
8558
8615
  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;
8559
8616
  const prototype = Object.getPrototypeOf(value);
8560
8617
  if ((prototype === null || prototype === Object.prototype) && hasGuestObjectState(value))
@@ -13512,11 +13569,11 @@ function createObjectArrayGlobals(options) {
13512
13569
  getOwnPropertyDescriptors: createSandboxClosure({
13513
13570
  sandbox: true,
13514
13571
  call: ([value]) => {
13515
- const descriptors = /* @__PURE__ */ Object.create(null);
13572
+ const descriptors2 = /* @__PURE__ */ Object.create(null);
13516
13573
  const properties = objectProperties(value);
13517
13574
  for (const key of [...Object.getOwnPropertyNames(properties), ...ownSandboxSymbolKeys(value)])
13518
- defineOwnDataProperty(descriptors, key, exposePropertyDescriptor(Object.getOwnPropertyDescriptor(properties, key)));
13519
- return allocateProducedSandboxValue(descriptors, options.budget);
13575
+ defineOwnDataProperty(descriptors2, key, exposePropertyDescriptor(Object.getOwnPropertyDescriptor(properties, key)));
13576
+ return allocateProducedSandboxValue(descriptors2, options.budget);
13520
13577
  },
13521
13578
  name: "getOwnPropertyDescriptors"
13522
13579
  }),
@@ -13547,8 +13604,8 @@ function createObjectArrayGlobals(options) {
13547
13604
  }),
13548
13605
  defineProperties: createSandboxClosure({
13549
13606
  sandbox: true,
13550
- call: async ([value, descriptors], context) => {
13551
- await definePropertiesFromObject(value, descriptors, options.budget, context);
13607
+ call: async ([value, descriptors2], context) => {
13608
+ await definePropertiesFromObject(value, descriptors2, options.budget, context);
13552
13609
  return value;
13553
13610
  },
13554
13611
  name: "defineProperties"
@@ -13577,12 +13634,12 @@ function createObjectArrayGlobals(options) {
13577
13634
  }),
13578
13635
  create: createSandboxClosure({
13579
13636
  sandbox: true,
13580
- call: async ([prototype, descriptors], context) => {
13637
+ call: async ([prototype, descriptors2], context) => {
13581
13638
  if (prototype !== null) objectProperties(prototype);
13582
13639
  const value = /* @__PURE__ */ Object.create(null);
13583
13640
  setSandboxPrototype(value, prototype, options.budget);
13584
- if (descriptors !== void 0) {
13585
- await definePropertiesFromObject(value, descriptors, options.budget, context);
13641
+ if (descriptors2 !== void 0) {
13642
+ await definePropertiesFromObject(value, descriptors2, options.budget, context);
13586
13643
  }
13587
13644
  return allocateProducedSandboxValue(value, options.budget);
13588
13645
  },
@@ -13931,19 +13988,19 @@ async function propertyDescriptor(input, budget, context) {
13931
13988
  release();
13932
13989
  }
13933
13990
  }
13934
- async function definePropertiesFromObject(target, descriptors, budget, context) {
13991
+ async function definePropertiesFromObject(target, descriptors2, budget, context) {
13935
13992
  objectProperties(target, true);
13936
13993
  const properties = [];
13937
13994
  const release = retainValues(budget, () => [
13938
13995
  target,
13939
- descriptors,
13996
+ descriptors2,
13940
13997
  properties,
13941
13998
  ...properties.flatMap(([, descriptor]) => retainedAccessorClosures(descriptor))
13942
13999
  ]);
13943
14000
  try {
13944
- for (const key of ownEnumerableSandboxKeys(descriptors, true)) {
13945
- if (!hasOwnSandboxProperty(descriptors, key, true)) continue;
13946
- const descriptor = await (context?.getProperty !== void 0 ? context.getProperty(descriptors, key) : getSandboxDataProperty(descriptors, key, budget));
14001
+ for (const key of ownEnumerableSandboxKeys(descriptors2, true)) {
14002
+ if (!hasOwnSandboxProperty(descriptors2, key, true)) continue;
14003
+ const descriptor = await (context?.getProperty !== void 0 ? context.getProperty(descriptors2, key) : getSandboxDataProperty(descriptors2, key, budget));
13947
14004
  properties.push([key, await propertyDescriptor(descriptor, budget, context)]);
13948
14005
  }
13949
14006
  for (const [key, descriptor] of properties) defineDataProperty(target, key, descriptor, budget);
@@ -16174,7 +16231,6 @@ function relativeIndex(value, length, fallback) {
16174
16231
  }
16175
16232
 
16176
16233
  // packages/safe-js/src/interp/interpreter.ts
16177
- var taggedTemplateRawArrays = /* @__PURE__ */ new WeakMap();
16178
16234
  var dispatchTable = {
16179
16235
  ArrayExpression: evaluateArrayExpression,
16180
16236
  AssignmentExpression: evaluateAssignmentExpression,
@@ -16649,7 +16705,7 @@ async function evaluateTaggedTemplateExpression(node, context) {
16649
16705
  hasValue: true,
16650
16706
  value: await invokeSandboxClosure(
16651
16707
  tag2,
16652
- [createTaggedTemplateStrings(node.quasi, context), ...values.value],
16708
+ [templateObject(node.quasi, context.budget), ...values.value],
16653
16709
  context,
16654
16710
  [...context.callStack, formatStackFrame(node, tag2.name)],
16655
16711
  node.span,
@@ -16674,24 +16730,6 @@ async function evaluateTaggedTemplateExpression(node, context) {
16674
16730
  const tag = await evaluateNode(node.tag, context);
16675
16731
  return tag.kind === "normal" ? invokeTag(tag.value, void 0) : tag;
16676
16732
  }
16677
- function createTaggedTemplateStrings(node, context) {
16678
- context.budget.allocateArrayLength(node.quasis.length);
16679
- const strings = node.quasis.map(
16680
- (quasi) => quasi.value.cooked === void 0 ? void 0 : context.budget.allocateString(quasi.value.cooked)
16681
- );
16682
- context.budget.allocateArrayLength(node.quasis.length);
16683
- const raw = node.quasis.map(
16684
- (quasi) => context.budget.allocateString(quasi.value.raw)
16685
- );
16686
- Object.defineProperty(strings, "raw", {
16687
- configurable: false,
16688
- enumerable: false,
16689
- value: raw,
16690
- writable: false
16691
- });
16692
- taggedTemplateRawArrays.set(strings, raw);
16693
- return strings;
16694
- }
16695
16733
  async function evaluateArrowFunction(node, context) {
16696
16734
  return evaluateArrowFunctionExpression(node, context, evaluateNode);
16697
16735
  }
@@ -18891,8 +18929,8 @@ function getMemberValue(target, property, context) {
18891
18929
  }
18892
18930
  function getArrayMemberValue(target, property, context) {
18893
18931
  if (hasExplicitSandboxPrototype(target)) return void 0;
18894
- if (property === "raw" && taggedTemplateRawArrays.has(target)) {
18895
- return taggedTemplateRawArrays.get(target);
18932
+ if (property === "raw" && templateRawArrays.has(target)) {
18933
+ return templateRawArrays.get(target);
18896
18934
  }
18897
18935
  return getArrayMember(target, property, createArrayMethodOptions(context));
18898
18936
  }
@@ -22290,9 +22328,9 @@ function absent(value) {
22290
22328
  const node = record2(value);
22291
22329
  return node.kind === "undefined" && Object.keys(node).length === 1;
22292
22330
  }
22293
- function validateGuestHeapNode(raw, heap) {
22331
+ function validateGuestHeapNode(raw, heap, maxArrayLength = 4294967295) {
22294
22332
  const node = record2(raw);
22295
- if (!["intrinsic", "guest-function", "guest-generator", "scope-frame", "guest-object"].includes(String(node.kind))) return false;
22333
+ if (!["intrinsic", "guest-function", "guest-generator", "scope-frame", "guest-object", "guest-array"].includes(String(node.kind))) return false;
22296
22334
  const reference = (value, kinds) => {
22297
22335
  const ref = record2(value);
22298
22336
  fields(ref, ["kind", "id"]);
@@ -22342,9 +22380,25 @@ function validateGuestHeapNode(raw, heap) {
22342
22380
  fields(node, ["kind", "id"], ["state"]);
22343
22381
  if (typeof node.id !== "string" || !intrinsicCatalogue().has(node.id)) throw new TypeError("Unknown intrinsic identity.");
22344
22382
  if (Object.hasOwn(node, "state")) state(node.state);
22345
- } else if (node.kind === "guest-object") {
22346
- fields(node, ["kind", "state"]);
22383
+ } else if (node.kind === "guest-object" || node.kind === "guest-array") {
22384
+ fields(node, ["kind", "state"], node.kind === "guest-array" ? ["templateNodeId", "templateOwner"] : []);
22385
+ if (Object.hasOwn(node, "templateOwner")) reference(node.templateOwner, ["guest-array"]);
22386
+ if (Object.hasOwn(node, "templateNodeId") && integer(node.templateNodeId) < 1)
22387
+ throw new TypeError("Invalid template source identity.");
22347
22388
  state(node.state);
22389
+ if (node.kind === "guest-array") {
22390
+ const properties = array(record2(record2(node.state).properties).properties).map((entry) => array(entry));
22391
+ const length = properties.find((entry) => entry[0] === "length");
22392
+ if (length === void 0) throw new TypeError("Missing guest array length.");
22393
+ const descriptor = record2(length[1]);
22394
+ if (descriptor.kind !== "data" || descriptor.configurable !== false || descriptor.enumerable !== false || integer(descriptor.value) > 4294967295) throw new TypeError("Invalid guest array length.");
22395
+ if (descriptor.value > maxArrayLength) throw new TypeError("Guest array length exceeds allocation limit.");
22396
+ for (const [key] of properties) {
22397
+ if (typeof key !== "string") continue;
22398
+ const index = Number(key);
22399
+ if (Number.isInteger(index) && index >= 0 && index < 4294967295 && String(index) === key && index >= descriptor.value) throw new TypeError("Guest array index exceeds length.");
22400
+ }
22401
+ }
22348
22402
  } else if (node.kind === "guest-function") {
22349
22403
  fields(node, ["kind", "astNodeId", "scope", "state"], ["name", "environment"]);
22350
22404
  if (integer(node.astNodeId) < 1) throw new TypeError("Invalid guest AST identity.");
@@ -22387,17 +22441,17 @@ function validateGuestHeapNode(raw, heap) {
22387
22441
  } else if (expression.kind === "array") {
22388
22442
  fields(expression, ["kind", "values", "index"]);
22389
22443
  integer(expression.index);
22390
- reference(expression.values, ["array"]);
22444
+ reference(expression.values, ["array", "guest-array"]);
22391
22445
  } else if (expression.kind === "call" || expression.kind === "new" || expression.kind === "tagged") {
22392
22446
  fields(expression, ["kind", "callee", "thisValue", "args", "index"]);
22393
22447
  integer(expression.index);
22394
- reference(expression.args, ["array"]);
22448
+ reference(expression.args, ["array", "guest-array"]);
22395
22449
  } else if (expression.kind === "array-call") {
22396
22450
  fields(expression, ["kind", "target", "method", "args", "index"]);
22397
22451
  if (typeof expression.method !== "string") throw new TypeError("Invalid array method.");
22398
22452
  integer(expression.index);
22399
- reference(expression.args, ["array"]);
22400
- reference(expression.target, ["array"]);
22453
+ reference(expression.args, ["array", "guest-array"]);
22454
+ reference(expression.target, ["array", "guest-array"]);
22401
22455
  } else throw new TypeError("Invalid expression continuation.");
22402
22456
  }
22403
22457
  }
@@ -22582,6 +22636,61 @@ function validateGuestFunctionAst(record3, origin) {
22582
22636
  }
22583
22637
  }
22584
22638
 
22639
+ // packages/safe-js/src/snapshot/template-validation.ts
22640
+ function validateTemplateObjects(heap, nodes) {
22641
+ const sites = /* @__PURE__ */ new Map();
22642
+ for (const node of nodes) {
22643
+ if (node.type === "TaggedTemplateExpression" && node.quasi.nodeId !== void 0)
22644
+ sites.set(node.quasi.nodeId, node.quasi);
22645
+ }
22646
+ const seen = /* @__PURE__ */ new Set();
22647
+ const rawOwners = /* @__PURE__ */ new Map();
22648
+ for (const raw of Object.values(heap)) {
22649
+ const entry = raw;
22650
+ if (entry.kind !== "guest-array" || entry.templateNodeId === void 0) continue;
22651
+ const node = sites.get(entry.templateNodeId);
22652
+ if (node === void 0 || seen.has(entry.templateNodeId)) throw new TypeError("Invalid or duplicate template source identity.");
22653
+ seen.add(entry.templateNodeId);
22654
+ const cooked = descriptors(entry.state);
22655
+ const rawReference = cooked.get("raw")?.value;
22656
+ const rawArray = rawReference?.kind === "ref" ? heap[String(rawReference.id)] : void 0;
22657
+ if (rawArray?.kind !== "guest-array") throw new TypeError("Invalid template raw array.");
22658
+ if (rawOwners.has(rawArray) && rawOwners.get(rawArray) !== raw) throw new TypeError("Conflicting template raw identity.");
22659
+ rawOwners.set(rawArray, raw);
22660
+ checkArray(cooked, node.quasis.map((quasi) => quasi.value.cooked), true);
22661
+ checkArray(descriptors(rawArray.state), node.quasis.map((quasi) => quasi.value.raw), false);
22662
+ }
22663
+ for (const [raw, owner] of rawOwners) {
22664
+ const reference = raw.templateOwner;
22665
+ if (reference === void 0 || heap[String(reference.id)] !== owner)
22666
+ throw new TypeError("Missing or invalid template owner identity.");
22667
+ }
22668
+ for (const raw of Object.values(heap)) {
22669
+ const entry = raw;
22670
+ if (entry.templateOwner !== void 0 && rawOwners.get(raw) !== heap[String(entry.templateOwner.id)])
22671
+ throw new TypeError("Invalid template owner identity.");
22672
+ }
22673
+ }
22674
+ function descriptors(raw) {
22675
+ const state = raw;
22676
+ if (Object.hasOwn(state, "prototype") || state.properties.extensible !== false)
22677
+ throw new TypeError("Invalid template object state.");
22678
+ return new Map(state.properties.properties);
22679
+ }
22680
+ function checkArray(properties, values, cooked) {
22681
+ if (properties.size !== values.length + (cooked ? 2 : 1)) throw new TypeError("Invalid template property count.");
22682
+ const expected = new Map(values.map((value, index) => [String(index), value]));
22683
+ expected.set("length", values.length);
22684
+ if (cooked) expected.set("raw", properties.get("raw")?.value);
22685
+ for (const [key, value] of expected) {
22686
+ const descriptor = properties.get(key);
22687
+ const actual = descriptor?.value;
22688
+ const equal = value === void 0 ? actual !== null && typeof actual === "object" && actual.kind === "undefined" : actual === value;
22689
+ if (descriptor?.kind !== "data" || descriptor.configurable !== false || descriptor.writable !== false || descriptor.enumerable !== (key !== "length" && key !== "raw") || !equal)
22690
+ throw new TypeError("Invalid template property descriptor or contents.");
22691
+ }
22692
+ }
22693
+
22585
22694
  // packages/safe-js/src/snapshot/validation.ts
22586
22695
  var DEFAULT_MAX_DEPTH = MAX_DATA_DEPTH;
22587
22696
  var DEFAULT_MAX_ENTRIES = 1e5;
@@ -22660,7 +22769,7 @@ function validateDumpHeap(root, state) {
22660
22769
  validateErrorType(entry, path);
22661
22770
  validateSymbolEntries(entry, path, state, heap);
22662
22771
  try {
22663
- if (validateGuestHeapNode(entry, heap)) {
22772
+ if (validateGuestHeapNode(entry, heap, state.limits.maxEntries)) {
22664
22773
  if (root.version !== 2) fail("unsupportedVersion", path, "guest heap records require dump version 2");
22665
22774
  continue;
22666
22775
  }
@@ -22889,7 +22998,7 @@ function validateGeneratorShape(record3, path, state) {
22889
22998
  function validateHeapValue(value, path, state, heap) {
22890
22999
  const record3 = requireRecord(value, path);
22891
23000
  try {
22892
- if (validateGuestHeapNode(record3, heap)) {
23001
+ if (validateGuestHeapNode(record3, heap, state.limits.maxEntries)) {
22893
23002
  const tagged = state.validateTaggedPayloads;
22894
23003
  state.validateTaggedPayloads = false;
22895
23004
  try {
@@ -23853,8 +23962,8 @@ function measureSandboxData(values, options = {}) {
23853
23962
  seen.add(value);
23854
23963
  usage += 1;
23855
23964
  if (!isGuestHostObject(value)) {
23856
- const descriptors2 = Object.getOwnPropertySymbols(value).filter((key) => !internalSymbols.has(key)).map((key) => [key, Object.getOwnPropertyDescriptor(value, key)]);
23857
- for (const [key, descriptor] of descriptors2) {
23965
+ const descriptors3 = Object.getOwnPropertySymbols(value).filter((key) => !internalSymbols.has(key)).map((key) => [key, Object.getOwnPropertyDescriptor(value, key)]);
23966
+ for (const [key, descriptor] of descriptors3) {
23858
23967
  usage += 1;
23859
23968
  visit(key, depth + 1);
23860
23969
  if ("value" in descriptor) visit(descriptor.value, depth + 1);
@@ -23990,16 +24099,16 @@ function measureSandboxData(values, options = {}) {
23990
24099
  }
23991
24100
  return;
23992
24101
  }
23993
- const descriptors = Object.getOwnPropertyDescriptors(value);
23994
- const keys = Object.keys(descriptors);
24102
+ const descriptors2 = Object.getOwnPropertyDescriptors(value);
24103
+ const keys = Object.keys(descriptors2);
23995
24104
  const includeNonEnumerable = isSandboxDate(value) || hasManagedDescriptors(value);
23996
24105
  let entryCount = 0;
23997
24106
  for (const key of keys) {
23998
- if (descriptors[key].enumerable || includeNonEnumerable) entryCount += 1;
24107
+ if (descriptors2[key].enumerable || includeNonEnumerable) entryCount += 1;
23999
24108
  }
24000
24109
  usage += entryCount;
24001
24110
  for (const key of keys) {
24002
- const descriptor = descriptors[key];
24111
+ const descriptor = descriptors2[key];
24003
24112
  if (!descriptor.enumerable && !includeNonEnumerable) continue;
24004
24113
  usage += key.length;
24005
24114
  if ("value" in descriptor) visit(descriptor.value, depth + 1);
@@ -24607,11 +24716,11 @@ function defineOwnDataProperty(target, key, value) {
24607
24716
  });
24608
24717
  }
24609
24718
  function getEnumerableObjectEntries(value, path) {
24610
- const descriptors = Object.getOwnPropertyDescriptors(value);
24719
+ const descriptors2 = Object.getOwnPropertyDescriptors(value);
24611
24720
  const entries = [];
24612
- for (const key of Reflect.ownKeys(descriptors)) {
24721
+ for (const key of Reflect.ownKeys(descriptors2)) {
24613
24722
  if (typeof key === "symbol" && internalSymbols.has(key)) continue;
24614
- const descriptor = Object.getOwnPropertyDescriptor(descriptors, key).value;
24723
+ const descriptor = Object.getOwnPropertyDescriptor(descriptors2, key).value;
24615
24724
  if (!descriptor.enumerable) {
24616
24725
  continue;
24617
24726
  }
@@ -24626,11 +24735,11 @@ function getEnumerableObjectEntries(value, path) {
24626
24735
  return entries;
24627
24736
  }
24628
24737
  function getEnumerableArrayEntries(value, path) {
24629
- const descriptors = Object.getOwnPropertyDescriptors(value);
24738
+ const descriptors2 = Object.getOwnPropertyDescriptors(value);
24630
24739
  const entries = [];
24631
- for (const key of Reflect.ownKeys(descriptors)) {
24740
+ for (const key of Reflect.ownKeys(descriptors2)) {
24632
24741
  if (typeof key === "symbol" && internalSymbols.has(key)) continue;
24633
- const descriptor = Object.getOwnPropertyDescriptor(descriptors, key).value;
24742
+ const descriptor = Object.getOwnPropertyDescriptor(descriptors2, key).value;
24634
24743
  if (key === "length" || !descriptor.enumerable) {
24635
24744
  continue;
24636
24745
  }
@@ -25292,9 +25401,9 @@ function normalize(value, seen) {
25292
25401
  return normalized2;
25293
25402
  }
25294
25403
  const normalized = /* @__PURE__ */ Object.create(null);
25295
- const descriptors = Object.getOwnPropertyDescriptors(value);
25296
- for (const key of Object.keys(descriptors).sort()) {
25297
- const descriptor = descriptors[key];
25404
+ const descriptors2 = Object.getOwnPropertyDescriptors(value);
25405
+ for (const key of Object.keys(descriptors2).sort()) {
25406
+ const descriptor = descriptors2[key];
25298
25407
  if (!descriptor.enumerable) continue;
25299
25408
  if (!("value" in descriptor)) {
25300
25409
  throw new TypeError("Host call arguments cannot contain accessor properties.");
@@ -25536,7 +25645,7 @@ function restore(snapshot, options, owner) {
25536
25645
  throw new SnapshotMismatchError(snapshot.sourceHash, currentSourceHash);
25537
25646
  }
25538
25647
  if (snapshot.heap !== void 0 && typeof snapshot.heap === "object" && snapshot.heap !== null) {
25539
- const closures = Object.entries(snapshot.heap).filter(([, value]) => value !== null && typeof value === "object" && ["guest-function", "guest-generator"].includes(String(value.kind)));
25648
+ 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));
25540
25649
  if (closures.length > 0) {
25541
25650
  const functions = /* @__PURE__ */ new Map();
25542
25651
  const pending = [parseModule(options.source, "<input>", owner)];
@@ -25544,13 +25653,14 @@ function restore(snapshot, options, owner) {
25544
25653
  const value = pending.pop();
25545
25654
  if (value === null || typeof value !== "object") continue;
25546
25655
  const node = value;
25547
- if (["ArrowFunctionExpression", "FunctionExpression", "FunctionDeclaration"].includes(String(node.type)) && typeof node.nodeId === "number") {
25656
+ if (typeof node.nodeId === "number") {
25548
25657
  functions.set(node.nodeId, node);
25549
25658
  }
25550
25659
  for (const entry of Object.values(node)) pending.push(entry);
25551
25660
  }
25552
25661
  for (const [id, value] of closures) {
25553
25662
  const record3 = value;
25663
+ if (record3.kind === "guest-array") continue;
25554
25664
  const origin = functions.get(record3.astNodeId);
25555
25665
  try {
25556
25666
  validateGuestFunctionAst(record3, origin);
@@ -25558,6 +25668,11 @@ function restore(snapshot, options, owner) {
25558
25668
  throw new SnapshotValidationError("invalidValue", `$.heap[${JSON.stringify(id)}].astNodeId`, error instanceof Error ? error.message : String(error));
25559
25669
  }
25560
25670
  }
25671
+ try {
25672
+ validateTemplateObjects(snapshot.heap, functions.values());
25673
+ } catch (error) {
25674
+ throw new SnapshotValidationError("invalidValue", "$.heap", String(error));
25675
+ }
25561
25676
  }
25562
25677
  }
25563
25678
  return snapshot;
@@ -38762,4 +38877,4 @@ export {
38762
38877
  FileSnapshotBackend,
38763
38878
  run
38764
38879
  };
38765
- //# sourceMappingURL=chunk-7DK7CIUK.js.map
38880
+ //# sourceMappingURL=chunk-PEHO3DVD.js.map