seroval 1.6.2 → 1.6.4

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.
@@ -197,6 +197,101 @@ function deserializeString(str) {
197
197
  return str.replace(/(\\\\|\\"|\\n|\\r|\\b|\\t|\\f|\\u2028|\\u2029|\\x3C)/g, deserializeReplacer);
198
198
  }
199
199
  //#endregion
200
+ //#region src/core/errors.ts
201
+ const { toString: objectToString } = Object.prototype;
202
+ function getErrorMessageDev(type, cause) {
203
+ if (cause instanceof Error) return `Seroval caught an error during the ${type} process.
204
+
205
+ ${cause.name}
206
+ ${cause.message}
207
+
208
+ - For more information, please check the "cause" property of this error.
209
+ - If you believe this is an error in Seroval, please submit an issue at https://github.com/lxsmnsyc/seroval/issues/new`;
210
+ return `Seroval caught an error during the ${type} process.
211
+
212
+ "${objectToString.call(cause)}"
213
+
214
+ For more information, please check the "cause" property of this error.`;
215
+ }
216
+ const getErrorMessage = (type, cause) => getErrorMessageDev(type, cause);
217
+ var SerovalError = class extends Error {
218
+ constructor(type, cause) {
219
+ super(getErrorMessage(type, cause));
220
+ this.cause = cause;
221
+ }
222
+ };
223
+ var SerovalParserError = class extends SerovalError {
224
+ constructor(cause) {
225
+ super("parsing", cause);
226
+ }
227
+ };
228
+ var SerovalSerializationError = class extends SerovalError {
229
+ constructor(cause) {
230
+ super("serialization", cause);
231
+ }
232
+ };
233
+ var SerovalDeserializationError = class extends SerovalError {
234
+ constructor(cause) {
235
+ super("deserialization", cause);
236
+ }
237
+ };
238
+ var SerovalUnsupportedTypeError = class extends Error {
239
+ constructor(value) {
240
+ super(`The value ${objectToString.call(value)} of type "${typeof value}" cannot be parsed/serialized.
241
+
242
+ There are few workarounds for this problem:
243
+ - Transform the value in a way that it can be serialized.
244
+ - If the reference is present on multiple runtimes (isomorphic), you can use the Reference API to map the references.`);
245
+ this.value = value;
246
+ }
247
+ };
248
+ var SerovalUnsupportedNodeError = class extends Error {
249
+ constructor(node) {
250
+ super("Unsupported node type \"" + node.t + "\".");
251
+ }
252
+ };
253
+ var SerovalMissingPluginError = class extends Error {
254
+ constructor(tag) {
255
+ super("Missing plugin for tag \"" + tag + "\".");
256
+ }
257
+ };
258
+ var SerovalMissingInstanceError = class extends Error {
259
+ constructor(tag) {
260
+ super("Missing \"" + tag + "\" instance.");
261
+ }
262
+ };
263
+ var SerovalMissingReferenceError = class extends Error {
264
+ constructor(value) {
265
+ super("Missing reference for the value \"" + objectToString.call(value) + "\" of type \"" + typeof value + "\"");
266
+ this.value = value;
267
+ }
268
+ };
269
+ var SerovalMissingReferenceForIdError = class extends Error {
270
+ constructor(id) {
271
+ super("Missing reference for id \"" + serializeString(id) + "\"");
272
+ }
273
+ };
274
+ var SerovalUnknownTypedArrayError = class extends Error {
275
+ constructor(name) {
276
+ super("Unknown TypedArray \"" + name + "\"");
277
+ }
278
+ };
279
+ var SerovalMalformedNodeError = class extends Error {
280
+ constructor(node) {
281
+ super("Malformed node type \"" + node.t + "\".");
282
+ }
283
+ };
284
+ var SerovalConflictedNodeIdError = class extends Error {
285
+ constructor(node) {
286
+ super("Conflicted node id \"" + node.i + "\".");
287
+ }
288
+ };
289
+ var SerovalDepthLimitError = class extends Error {
290
+ constructor(limit) {
291
+ super("Depth limit of " + limit + " reached");
292
+ }
293
+ };
294
+ //#endregion
200
295
  //#region src/core/keys.ts
201
296
  const REFERENCES_KEY = "__SEROVAL_REFS__";
202
297
  const GLOBAL_CONTEXT_R = `self.\$R`;
@@ -273,14 +368,16 @@ function getErrorOptions(error, features) {
273
368
  const names = Object.getOwnPropertyNames(error);
274
369
  for (let i = 0, len = names.length, name; i < len; i++) {
275
370
  name = names[i];
276
- if (name !== "name" && name !== "message") if (name === "stack") {
277
- if (features & 4) {
371
+ if (name !== "name" && name !== "message") {
372
+ if (name === "stack") {
373
+ if (features & 4) {
374
+ options = options || {};
375
+ options[name] = error[name];
376
+ }
377
+ } else {
278
378
  options = options || {};
279
379
  options[name] = error[name];
280
380
  }
281
- } else {
282
- options = options || {};
283
- options[name] = error[name];
284
381
  }
285
382
  }
286
383
  return options;
@@ -338,13 +435,17 @@ function createArrayNode(id, current, parsedItems) {
338
435
  function createBoxedNode(id, boxed) {
339
436
  return createSerovalNode(21, id, void 0, void 0, void 0, void 0, void 0, void 0, boxed, void 0, void 0, void 0);
340
437
  }
438
+ const MAX_TYPED_ARRAY_LENGTH = 1e6;
341
439
  function createTypedArrayNode(id, current, buffer) {
440
+ if (current.length > MAX_TYPED_ARRAY_LENGTH) throw new SerovalUnsupportedTypeError(current);
342
441
  return createSerovalNode(15, id, void 0, current.constructor.name, void 0, void 0, void 0, void 0, buffer, current.byteOffset, void 0, current.length);
343
442
  }
344
443
  function createBigIntTypedArrayNode(id, current, buffer) {
444
+ if (current.length > MAX_TYPED_ARRAY_LENGTH) throw new SerovalUnsupportedTypeError(current);
345
445
  return createSerovalNode(16, id, void 0, current.constructor.name, void 0, void 0, void 0, void 0, buffer, current.byteOffset, void 0, current.length);
346
446
  }
347
447
  function createDataViewNode(id, current, buffer) {
448
+ if (current.byteLength > MAX_TYPED_ARRAY_LENGTH) throw new SerovalUnsupportedTypeError(current);
348
449
  return createSerovalNode(20, id, void 0, void 0, void 0, void 0, void 0, void 0, buffer, current.byteOffset, void 0, current.byteLength);
349
450
  }
350
451
  function createErrorNode(id, current, options) {
@@ -378,101 +479,6 @@ function createSequenceNode(id, sequence, throwAt, doneAt) {
378
479
  return createSerovalNode(35, id, throwAt, void 0, void 0, void 0, void 0, sequence, void 0, void 0, void 0, doneAt);
379
480
  }
380
481
  //#endregion
381
- //#region src/core/errors.ts
382
- const { toString: objectToString } = Object.prototype;
383
- function getErrorMessageDev(type, cause) {
384
- if (cause instanceof Error) return `Seroval caught an error during the ${type} process.
385
-
386
- ${cause.name}
387
- ${cause.message}
388
-
389
- - For more information, please check the "cause" property of this error.
390
- - If you believe this is an error in Seroval, please submit an issue at https://github.com/lxsmnsyc/seroval/issues/new`;
391
- return `Seroval caught an error during the ${type} process.
392
-
393
- "${objectToString.call(cause)}"
394
-
395
- For more information, please check the "cause" property of this error.`;
396
- }
397
- const getErrorMessage = (type, cause) => getErrorMessageDev(type, cause);
398
- var SerovalError = class extends Error {
399
- constructor(type, cause) {
400
- super(getErrorMessage(type, cause));
401
- this.cause = cause;
402
- }
403
- };
404
- var SerovalParserError = class extends SerovalError {
405
- constructor(cause) {
406
- super("parsing", cause);
407
- }
408
- };
409
- var SerovalSerializationError = class extends SerovalError {
410
- constructor(cause) {
411
- super("serialization", cause);
412
- }
413
- };
414
- var SerovalDeserializationError = class extends SerovalError {
415
- constructor(cause) {
416
- super("deserialization", cause);
417
- }
418
- };
419
- var SerovalUnsupportedTypeError = class extends Error {
420
- constructor(value) {
421
- super(`The value ${objectToString.call(value)} of type "${typeof value}" cannot be parsed/serialized.
422
-
423
- There are few workarounds for this problem:
424
- - Transform the value in a way that it can be serialized.
425
- - If the reference is present on multiple runtimes (isomorphic), you can use the Reference API to map the references.`);
426
- this.value = value;
427
- }
428
- };
429
- var SerovalUnsupportedNodeError = class extends Error {
430
- constructor(node) {
431
- super("Unsupported node type \"" + node.t + "\".");
432
- }
433
- };
434
- var SerovalMissingPluginError = class extends Error {
435
- constructor(tag) {
436
- super("Missing plugin for tag \"" + tag + "\".");
437
- }
438
- };
439
- var SerovalMissingInstanceError = class extends Error {
440
- constructor(tag) {
441
- super("Missing \"" + tag + "\" instance.");
442
- }
443
- };
444
- var SerovalMissingReferenceError = class extends Error {
445
- constructor(value) {
446
- super("Missing reference for the value \"" + objectToString.call(value) + "\" of type \"" + typeof value + "\"");
447
- this.value = value;
448
- }
449
- };
450
- var SerovalMissingReferenceForIdError = class extends Error {
451
- constructor(id) {
452
- super("Missing reference for id \"" + serializeString(id) + "\"");
453
- }
454
- };
455
- var SerovalUnknownTypedArrayError = class extends Error {
456
- constructor(name) {
457
- super("Unknown TypedArray \"" + name + "\"");
458
- }
459
- };
460
- var SerovalMalformedNodeError = class extends Error {
461
- constructor(node) {
462
- super("Malformed node type \"" + node.t + "\".");
463
- }
464
- };
465
- var SerovalConflictedNodeIdError = class extends Error {
466
- constructor(node) {
467
- super("Conflicted node id \"" + node.i + "\".");
468
- }
469
- };
470
- var SerovalDepthLimitError = class extends Error {
471
- constructor(limit) {
472
- super("Depth limit of " + limit + " reached");
473
- }
474
- };
475
- //#endregion
476
482
  //#region src/core/opaque-reference.ts
477
483
  /**
478
484
  * An opaque reference allows hiding values from the serializer.
@@ -1060,7 +1066,6 @@ async function parseObjectAsync(ctx, depth, id, current) {
1060
1066
  case DataView: return parseDataView$1(ctx, depth, id, current);
1061
1067
  case Map: return parseMap$1(ctx, depth, id, current);
1062
1068
  case Set: return parseSet$1(ctx, depth, id, current);
1063
- default: break;
1064
1069
  }
1065
1070
  if (currentClass === Promise || current instanceof Promise) return parsePromise$1(ctx, depth, id, current);
1066
1071
  const currentFeatures = ctx.base.features;
@@ -1068,7 +1073,6 @@ async function parseObjectAsync(ctx, depth, id, current) {
1068
1073
  if (currentFeatures & 16) switch (currentClass) {
1069
1074
  case BigInt64Array:
1070
1075
  case BigUint64Array: return parseBigIntTypedArray$1(ctx, depth, id, current);
1071
- default: break;
1072
1076
  }
1073
1077
  if (currentFeatures & 1 && typeof AggregateError !== "undefined" && (currentClass === AggregateError || current instanceof AggregateError)) return parseAggregateError$1(ctx, depth, id, current);
1074
1078
  if (currentFeatures & 64 && typeof Temporal !== "undefined") switch (currentClass) {
@@ -1080,7 +1084,6 @@ async function parseObjectAsync(ctx, depth, id, current) {
1080
1084
  case Temporal.PlainTime: return createTemporalNode(id, 5, current);
1081
1085
  case Temporal.PlainYearMonth: return createTemporalNode(id, 6, current);
1082
1086
  case Temporal.ZonedDateTime: return createTemporalNode(id, 7, current);
1083
- default: break;
1084
1087
  }
1085
1088
  if (current instanceof Error) return parseError$1(ctx, depth, id, current);
1086
1089
  if (SYM_ITERATOR in current || SYM_ASYNC_ITERATOR in current) return parsePlainObject$1(ctx, depth, id, current, !!currentClass);
@@ -1379,15 +1382,17 @@ function deserializeTypedArray(ctx, depth, node) {
1379
1382
  var _node$b;
1380
1383
  const construct = getTypedArrayConstructor(node.c);
1381
1384
  const source = deserialize$1(ctx, depth, node.f);
1385
+ if (!(source instanceof ArrayBuffer)) throw new SerovalMalformedNodeError(node);
1382
1386
  const offset = (_node$b = node.b) !== null && _node$b !== void 0 ? _node$b : 0;
1383
- if (offset < 0 || offset > source.byteLength) throw new SerovalMalformedNodeError(node);
1387
+ if (offset < 0 || offset > source.byteLength || node.l > MAX_BASE64_LENGTH) throw new SerovalMalformedNodeError(node);
1384
1388
  return assignIndexedValue$1(ctx, node.i, new construct(source, offset, node.l));
1385
1389
  }
1386
1390
  function deserializeDataView(ctx, depth, node) {
1387
1391
  var _node$b2;
1388
1392
  const source = deserialize$1(ctx, depth, node.f);
1393
+ if (!(source instanceof ArrayBuffer)) throw new SerovalMalformedNodeError(node);
1389
1394
  const offset = (_node$b2 = node.b) !== null && _node$b2 !== void 0 ? _node$b2 : 0;
1390
- if (offset < 0 || offset > source.byteLength) throw new SerovalMalformedNodeError(node);
1395
+ if (offset < 0 || offset > source.byteLength || node.l > MAX_BASE64_LENGTH) throw new SerovalMalformedNodeError(node);
1391
1396
  return assignIndexedValue$1(ctx, node.i, new DataView(source, offset, node.l));
1392
1397
  }
1393
1398
  function deserializeDictionary(ctx, depth, node, result) {
@@ -1446,11 +1451,15 @@ function deserializePromiseFulfill(ctx, depth, node) {
1446
1451
  }
1447
1452
  function deserializeIteratorFactoryInstance(ctx, depth, node) {
1448
1453
  deserialize$1(ctx, depth, node.a[0]);
1449
- return sequenceToIterator(deserialize$1(ctx, depth, node.a[1]));
1454
+ const source = deserialize$1(ctx, depth, node.a[1]);
1455
+ if (!source || typeof source !== "object" || !isSequence(source)) throw new SerovalMalformedNodeError(node.a[1]);
1456
+ return sequenceToIterator(source);
1450
1457
  }
1451
1458
  function deserializeAsyncIteratorFactoryInstance(ctx, depth, node) {
1452
1459
  deserialize$1(ctx, depth, node.a[0]);
1453
- return streamToAsyncIterable(deserialize$1(ctx, depth, node.a[1]));
1460
+ const source = deserialize$1(ctx, depth, node.a[1]);
1461
+ if (!source || typeof source !== "object" || !isStream(source)) throw new SerovalMalformedNodeError(node.a[1]);
1462
+ return streamToAsyncIterable(source);
1454
1463
  }
1455
1464
  function deserializeStreamConstructor(ctx, depth, node) {
1456
1465
  const result = assignIndexedValue$1(ctx, node.i, createStream());
@@ -1922,9 +1931,10 @@ function serializeStringKeyAssignment(ctx, source, mainAssignments, key, value)
1922
1931
  const serialized = serialize$1(ctx, value);
1923
1932
  const check = Number(key);
1924
1933
  const isIdentifier = check >= 0 && check.toString() === key || isValidIdentifier(key);
1925
- if (isIndexedValueInStack(base, value)) if (isIdentifier && check !== check) createObjectAssign(ctx, source.i, key, serialized);
1926
- else createArrayAssign(ctx, source.i, isIdentifier ? key : "\"" + key + "\"", serialized);
1927
- else {
1934
+ if (isIndexedValueInStack(base, value)) {
1935
+ if (isIdentifier && check !== check) createObjectAssign(ctx, source.i, key, serialized);
1936
+ else createArrayAssign(ctx, source.i, isIdentifier ? key : "\"" + key + "\"", serialized);
1937
+ } else {
1928
1938
  const parentAssignment = base.assignments;
1929
1939
  base.assignments = mainAssignments;
1930
1940
  if (isIdentifier && check !== check) createObjectAssign(ctx, source.i, key, serialized);
@@ -2551,7 +2561,6 @@ function parseObjectPhase2(ctx, depth, id, current, currentClass) {
2551
2561
  case DataView: return parseDataView(ctx, depth, id, current);
2552
2562
  case Map: return parseMap(ctx, depth, id, current);
2553
2563
  case Set: return parseSet(ctx, depth, id, current);
2554
- default: break;
2555
2564
  }
2556
2565
  if (currentClass === Promise || current instanceof Promise) return parsePromise(ctx, depth, id, current);
2557
2566
  const currentFeatures = ctx.base.features;
@@ -2559,7 +2568,6 @@ function parseObjectPhase2(ctx, depth, id, current, currentClass) {
2559
2568
  if (currentFeatures & 16) switch (currentClass) {
2560
2569
  case BigInt64Array:
2561
2570
  case BigUint64Array: return parseBigIntTypedArray(ctx, depth, id, current);
2562
- default: break;
2563
2571
  }
2564
2572
  if (currentFeatures & 1 && typeof AggregateError !== "undefined" && (currentClass === AggregateError || current instanceof AggregateError)) return parseAggregateError(ctx, depth, id, current);
2565
2573
  if (currentFeatures & 64 && typeof Temporal !== "undefined") switch (currentClass) {
@@ -2571,7 +2579,6 @@ function parseObjectPhase2(ctx, depth, id, current, currentClass) {
2571
2579
  case Temporal.PlainTime: return createTemporalNode(id, 5, current);
2572
2580
  case Temporal.PlainYearMonth: return createTemporalNode(id, 6, current);
2573
2581
  case Temporal.ZonedDateTime: return createTemporalNode(id, 7, current);
2574
- default: break;
2575
2582
  }
2576
2583
  if (current instanceof Error) return parseError(ctx, depth, id, current);
2577
2584
  if (SYM_ITERATOR in current || SYM_ASYNC_ITERATOR in current) return parsePlainObject(ctx, depth, id, current, !!currentClass);
package/dist/dev/index.js CHANGED
@@ -196,6 +196,101 @@ function deserializeString(str) {
196
196
  return str.replace(/(\\\\|\\"|\\n|\\r|\\b|\\t|\\f|\\u2028|\\u2029|\\x3C)/g, deserializeReplacer);
197
197
  }
198
198
  //#endregion
199
+ //#region src/core/errors.ts
200
+ const { toString: objectToString } = Object.prototype;
201
+ function getErrorMessageDev(type, cause) {
202
+ if (cause instanceof Error) return `Seroval caught an error during the ${type} process.
203
+
204
+ ${cause.name}
205
+ ${cause.message}
206
+
207
+ - For more information, please check the "cause" property of this error.
208
+ - If you believe this is an error in Seroval, please submit an issue at https://github.com/lxsmnsyc/seroval/issues/new`;
209
+ return `Seroval caught an error during the ${type} process.
210
+
211
+ "${objectToString.call(cause)}"
212
+
213
+ For more information, please check the "cause" property of this error.`;
214
+ }
215
+ const getErrorMessage = (type, cause) => getErrorMessageDev(type, cause);
216
+ var SerovalError = class extends Error {
217
+ constructor(type, cause) {
218
+ super(getErrorMessage(type, cause));
219
+ this.cause = cause;
220
+ }
221
+ };
222
+ var SerovalParserError = class extends SerovalError {
223
+ constructor(cause) {
224
+ super("parsing", cause);
225
+ }
226
+ };
227
+ var SerovalSerializationError = class extends SerovalError {
228
+ constructor(cause) {
229
+ super("serialization", cause);
230
+ }
231
+ };
232
+ var SerovalDeserializationError = class extends SerovalError {
233
+ constructor(cause) {
234
+ super("deserialization", cause);
235
+ }
236
+ };
237
+ var SerovalUnsupportedTypeError = class extends Error {
238
+ constructor(value) {
239
+ super(`The value ${objectToString.call(value)} of type "${typeof value}" cannot be parsed/serialized.
240
+
241
+ There are few workarounds for this problem:
242
+ - Transform the value in a way that it can be serialized.
243
+ - If the reference is present on multiple runtimes (isomorphic), you can use the Reference API to map the references.`);
244
+ this.value = value;
245
+ }
246
+ };
247
+ var SerovalUnsupportedNodeError = class extends Error {
248
+ constructor(node) {
249
+ super("Unsupported node type \"" + node.t + "\".");
250
+ }
251
+ };
252
+ var SerovalMissingPluginError = class extends Error {
253
+ constructor(tag) {
254
+ super("Missing plugin for tag \"" + tag + "\".");
255
+ }
256
+ };
257
+ var SerovalMissingInstanceError = class extends Error {
258
+ constructor(tag) {
259
+ super("Missing \"" + tag + "\" instance.");
260
+ }
261
+ };
262
+ var SerovalMissingReferenceError = class extends Error {
263
+ constructor(value) {
264
+ super("Missing reference for the value \"" + objectToString.call(value) + "\" of type \"" + typeof value + "\"");
265
+ this.value = value;
266
+ }
267
+ };
268
+ var SerovalMissingReferenceForIdError = class extends Error {
269
+ constructor(id) {
270
+ super("Missing reference for id \"" + serializeString(id) + "\"");
271
+ }
272
+ };
273
+ var SerovalUnknownTypedArrayError = class extends Error {
274
+ constructor(name) {
275
+ super("Unknown TypedArray \"" + name + "\"");
276
+ }
277
+ };
278
+ var SerovalMalformedNodeError = class extends Error {
279
+ constructor(node) {
280
+ super("Malformed node type \"" + node.t + "\".");
281
+ }
282
+ };
283
+ var SerovalConflictedNodeIdError = class extends Error {
284
+ constructor(node) {
285
+ super("Conflicted node id \"" + node.i + "\".");
286
+ }
287
+ };
288
+ var SerovalDepthLimitError = class extends Error {
289
+ constructor(limit) {
290
+ super("Depth limit of " + limit + " reached");
291
+ }
292
+ };
293
+ //#endregion
199
294
  //#region src/core/keys.ts
200
295
  const REFERENCES_KEY = "__SEROVAL_REFS__";
201
296
  const GLOBAL_CONTEXT_R = `self.\$R`;
@@ -272,14 +367,16 @@ function getErrorOptions(error, features) {
272
367
  const names = Object.getOwnPropertyNames(error);
273
368
  for (let i = 0, len = names.length, name; i < len; i++) {
274
369
  name = names[i];
275
- if (name !== "name" && name !== "message") if (name === "stack") {
276
- if (features & 4) {
370
+ if (name !== "name" && name !== "message") {
371
+ if (name === "stack") {
372
+ if (features & 4) {
373
+ options = options || {};
374
+ options[name] = error[name];
375
+ }
376
+ } else {
277
377
  options = options || {};
278
378
  options[name] = error[name];
279
379
  }
280
- } else {
281
- options = options || {};
282
- options[name] = error[name];
283
380
  }
284
381
  }
285
382
  return options;
@@ -337,13 +434,17 @@ function createArrayNode(id, current, parsedItems) {
337
434
  function createBoxedNode(id, boxed) {
338
435
  return createSerovalNode(21, id, void 0, void 0, void 0, void 0, void 0, void 0, boxed, void 0, void 0, void 0);
339
436
  }
437
+ const MAX_TYPED_ARRAY_LENGTH = 1e6;
340
438
  function createTypedArrayNode(id, current, buffer) {
439
+ if (current.length > MAX_TYPED_ARRAY_LENGTH) throw new SerovalUnsupportedTypeError(current);
341
440
  return createSerovalNode(15, id, void 0, current.constructor.name, void 0, void 0, void 0, void 0, buffer, current.byteOffset, void 0, current.length);
342
441
  }
343
442
  function createBigIntTypedArrayNode(id, current, buffer) {
443
+ if (current.length > MAX_TYPED_ARRAY_LENGTH) throw new SerovalUnsupportedTypeError(current);
344
444
  return createSerovalNode(16, id, void 0, current.constructor.name, void 0, void 0, void 0, void 0, buffer, current.byteOffset, void 0, current.length);
345
445
  }
346
446
  function createDataViewNode(id, current, buffer) {
447
+ if (current.byteLength > MAX_TYPED_ARRAY_LENGTH) throw new SerovalUnsupportedTypeError(current);
347
448
  return createSerovalNode(20, id, void 0, void 0, void 0, void 0, void 0, void 0, buffer, current.byteOffset, void 0, current.byteLength);
348
449
  }
349
450
  function createErrorNode(id, current, options) {
@@ -377,101 +478,6 @@ function createSequenceNode(id, sequence, throwAt, doneAt) {
377
478
  return createSerovalNode(35, id, throwAt, void 0, void 0, void 0, void 0, sequence, void 0, void 0, void 0, doneAt);
378
479
  }
379
480
  //#endregion
380
- //#region src/core/errors.ts
381
- const { toString: objectToString } = Object.prototype;
382
- function getErrorMessageDev(type, cause) {
383
- if (cause instanceof Error) return `Seroval caught an error during the ${type} process.
384
-
385
- ${cause.name}
386
- ${cause.message}
387
-
388
- - For more information, please check the "cause" property of this error.
389
- - If you believe this is an error in Seroval, please submit an issue at https://github.com/lxsmnsyc/seroval/issues/new`;
390
- return `Seroval caught an error during the ${type} process.
391
-
392
- "${objectToString.call(cause)}"
393
-
394
- For more information, please check the "cause" property of this error.`;
395
- }
396
- const getErrorMessage = (type, cause) => getErrorMessageDev(type, cause);
397
- var SerovalError = class extends Error {
398
- constructor(type, cause) {
399
- super(getErrorMessage(type, cause));
400
- this.cause = cause;
401
- }
402
- };
403
- var SerovalParserError = class extends SerovalError {
404
- constructor(cause) {
405
- super("parsing", cause);
406
- }
407
- };
408
- var SerovalSerializationError = class extends SerovalError {
409
- constructor(cause) {
410
- super("serialization", cause);
411
- }
412
- };
413
- var SerovalDeserializationError = class extends SerovalError {
414
- constructor(cause) {
415
- super("deserialization", cause);
416
- }
417
- };
418
- var SerovalUnsupportedTypeError = class extends Error {
419
- constructor(value) {
420
- super(`The value ${objectToString.call(value)} of type "${typeof value}" cannot be parsed/serialized.
421
-
422
- There are few workarounds for this problem:
423
- - Transform the value in a way that it can be serialized.
424
- - If the reference is present on multiple runtimes (isomorphic), you can use the Reference API to map the references.`);
425
- this.value = value;
426
- }
427
- };
428
- var SerovalUnsupportedNodeError = class extends Error {
429
- constructor(node) {
430
- super("Unsupported node type \"" + node.t + "\".");
431
- }
432
- };
433
- var SerovalMissingPluginError = class extends Error {
434
- constructor(tag) {
435
- super("Missing plugin for tag \"" + tag + "\".");
436
- }
437
- };
438
- var SerovalMissingInstanceError = class extends Error {
439
- constructor(tag) {
440
- super("Missing \"" + tag + "\" instance.");
441
- }
442
- };
443
- var SerovalMissingReferenceError = class extends Error {
444
- constructor(value) {
445
- super("Missing reference for the value \"" + objectToString.call(value) + "\" of type \"" + typeof value + "\"");
446
- this.value = value;
447
- }
448
- };
449
- var SerovalMissingReferenceForIdError = class extends Error {
450
- constructor(id) {
451
- super("Missing reference for id \"" + serializeString(id) + "\"");
452
- }
453
- };
454
- var SerovalUnknownTypedArrayError = class extends Error {
455
- constructor(name) {
456
- super("Unknown TypedArray \"" + name + "\"");
457
- }
458
- };
459
- var SerovalMalformedNodeError = class extends Error {
460
- constructor(node) {
461
- super("Malformed node type \"" + node.t + "\".");
462
- }
463
- };
464
- var SerovalConflictedNodeIdError = class extends Error {
465
- constructor(node) {
466
- super("Conflicted node id \"" + node.i + "\".");
467
- }
468
- };
469
- var SerovalDepthLimitError = class extends Error {
470
- constructor(limit) {
471
- super("Depth limit of " + limit + " reached");
472
- }
473
- };
474
- //#endregion
475
481
  //#region src/core/opaque-reference.ts
476
482
  /**
477
483
  * An opaque reference allows hiding values from the serializer.
@@ -1059,7 +1065,6 @@ async function parseObjectAsync(ctx, depth, id, current) {
1059
1065
  case DataView: return parseDataView$1(ctx, depth, id, current);
1060
1066
  case Map: return parseMap$1(ctx, depth, id, current);
1061
1067
  case Set: return parseSet$1(ctx, depth, id, current);
1062
- default: break;
1063
1068
  }
1064
1069
  if (currentClass === Promise || current instanceof Promise) return parsePromise$1(ctx, depth, id, current);
1065
1070
  const currentFeatures = ctx.base.features;
@@ -1067,7 +1072,6 @@ async function parseObjectAsync(ctx, depth, id, current) {
1067
1072
  if (currentFeatures & 16) switch (currentClass) {
1068
1073
  case BigInt64Array:
1069
1074
  case BigUint64Array: return parseBigIntTypedArray$1(ctx, depth, id, current);
1070
- default: break;
1071
1075
  }
1072
1076
  if (currentFeatures & 1 && typeof AggregateError !== "undefined" && (currentClass === AggregateError || current instanceof AggregateError)) return parseAggregateError$1(ctx, depth, id, current);
1073
1077
  if (currentFeatures & 64 && typeof Temporal !== "undefined") switch (currentClass) {
@@ -1079,7 +1083,6 @@ async function parseObjectAsync(ctx, depth, id, current) {
1079
1083
  case Temporal.PlainTime: return createTemporalNode(id, 5, current);
1080
1084
  case Temporal.PlainYearMonth: return createTemporalNode(id, 6, current);
1081
1085
  case Temporal.ZonedDateTime: return createTemporalNode(id, 7, current);
1082
- default: break;
1083
1086
  }
1084
1087
  if (current instanceof Error) return parseError$1(ctx, depth, id, current);
1085
1088
  if (SYM_ITERATOR in current || SYM_ASYNC_ITERATOR in current) return parsePlainObject$1(ctx, depth, id, current, !!currentClass);
@@ -1378,15 +1381,17 @@ function deserializeTypedArray(ctx, depth, node) {
1378
1381
  var _node$b;
1379
1382
  const construct = getTypedArrayConstructor(node.c);
1380
1383
  const source = deserialize$1(ctx, depth, node.f);
1384
+ if (!(source instanceof ArrayBuffer)) throw new SerovalMalformedNodeError(node);
1381
1385
  const offset = (_node$b = node.b) !== null && _node$b !== void 0 ? _node$b : 0;
1382
- if (offset < 0 || offset > source.byteLength) throw new SerovalMalformedNodeError(node);
1386
+ if (offset < 0 || offset > source.byteLength || node.l > MAX_BASE64_LENGTH) throw new SerovalMalformedNodeError(node);
1383
1387
  return assignIndexedValue$1(ctx, node.i, new construct(source, offset, node.l));
1384
1388
  }
1385
1389
  function deserializeDataView(ctx, depth, node) {
1386
1390
  var _node$b2;
1387
1391
  const source = deserialize$1(ctx, depth, node.f);
1392
+ if (!(source instanceof ArrayBuffer)) throw new SerovalMalformedNodeError(node);
1388
1393
  const offset = (_node$b2 = node.b) !== null && _node$b2 !== void 0 ? _node$b2 : 0;
1389
- if (offset < 0 || offset > source.byteLength) throw new SerovalMalformedNodeError(node);
1394
+ if (offset < 0 || offset > source.byteLength || node.l > MAX_BASE64_LENGTH) throw new SerovalMalformedNodeError(node);
1390
1395
  return assignIndexedValue$1(ctx, node.i, new DataView(source, offset, node.l));
1391
1396
  }
1392
1397
  function deserializeDictionary(ctx, depth, node, result) {
@@ -1445,11 +1450,15 @@ function deserializePromiseFulfill(ctx, depth, node) {
1445
1450
  }
1446
1451
  function deserializeIteratorFactoryInstance(ctx, depth, node) {
1447
1452
  deserialize$1(ctx, depth, node.a[0]);
1448
- return sequenceToIterator(deserialize$1(ctx, depth, node.a[1]));
1453
+ const source = deserialize$1(ctx, depth, node.a[1]);
1454
+ if (!source || typeof source !== "object" || !isSequence(source)) throw new SerovalMalformedNodeError(node.a[1]);
1455
+ return sequenceToIterator(source);
1449
1456
  }
1450
1457
  function deserializeAsyncIteratorFactoryInstance(ctx, depth, node) {
1451
1458
  deserialize$1(ctx, depth, node.a[0]);
1452
- return streamToAsyncIterable(deserialize$1(ctx, depth, node.a[1]));
1459
+ const source = deserialize$1(ctx, depth, node.a[1]);
1460
+ if (!source || typeof source !== "object" || !isStream(source)) throw new SerovalMalformedNodeError(node.a[1]);
1461
+ return streamToAsyncIterable(source);
1453
1462
  }
1454
1463
  function deserializeStreamConstructor(ctx, depth, node) {
1455
1464
  const result = assignIndexedValue$1(ctx, node.i, createStream());
@@ -1921,9 +1930,10 @@ function serializeStringKeyAssignment(ctx, source, mainAssignments, key, value)
1921
1930
  const serialized = serialize$1(ctx, value);
1922
1931
  const check = Number(key);
1923
1932
  const isIdentifier = check >= 0 && check.toString() === key || isValidIdentifier(key);
1924
- if (isIndexedValueInStack(base, value)) if (isIdentifier && check !== check) createObjectAssign(ctx, source.i, key, serialized);
1925
- else createArrayAssign(ctx, source.i, isIdentifier ? key : "\"" + key + "\"", serialized);
1926
- else {
1933
+ if (isIndexedValueInStack(base, value)) {
1934
+ if (isIdentifier && check !== check) createObjectAssign(ctx, source.i, key, serialized);
1935
+ else createArrayAssign(ctx, source.i, isIdentifier ? key : "\"" + key + "\"", serialized);
1936
+ } else {
1927
1937
  const parentAssignment = base.assignments;
1928
1938
  base.assignments = mainAssignments;
1929
1939
  if (isIdentifier && check !== check) createObjectAssign(ctx, source.i, key, serialized);
@@ -2550,7 +2560,6 @@ function parseObjectPhase2(ctx, depth, id, current, currentClass) {
2550
2560
  case DataView: return parseDataView(ctx, depth, id, current);
2551
2561
  case Map: return parseMap(ctx, depth, id, current);
2552
2562
  case Set: return parseSet(ctx, depth, id, current);
2553
- default: break;
2554
2563
  }
2555
2564
  if (currentClass === Promise || current instanceof Promise) return parsePromise(ctx, depth, id, current);
2556
2565
  const currentFeatures = ctx.base.features;
@@ -2558,7 +2567,6 @@ function parseObjectPhase2(ctx, depth, id, current, currentClass) {
2558
2567
  if (currentFeatures & 16) switch (currentClass) {
2559
2568
  case BigInt64Array:
2560
2569
  case BigUint64Array: return parseBigIntTypedArray(ctx, depth, id, current);
2561
- default: break;
2562
2570
  }
2563
2571
  if (currentFeatures & 1 && typeof AggregateError !== "undefined" && (currentClass === AggregateError || current instanceof AggregateError)) return parseAggregateError(ctx, depth, id, current);
2564
2572
  if (currentFeatures & 64 && typeof Temporal !== "undefined") switch (currentClass) {
@@ -2570,7 +2578,6 @@ function parseObjectPhase2(ctx, depth, id, current, currentClass) {
2570
2578
  case Temporal.PlainTime: return createTemporalNode(id, 5, current);
2571
2579
  case Temporal.PlainYearMonth: return createTemporalNode(id, 6, current);
2572
2580
  case Temporal.ZonedDateTime: return createTemporalNode(id, 7, current);
2573
- default: break;
2574
2581
  }
2575
2582
  if (current instanceof Error) return parseError(ctx, depth, id, current);
2576
2583
  if (SYM_ITERATOR in current || SYM_ASYNC_ITERATOR in current) return parsePlainObject(ctx, depth, id, current, !!currentClass);
package/dist/index.cjs CHANGED
@@ -197,6 +197,94 @@ function deserializeString(str) {
197
197
  return str.replace(/(\\\\|\\"|\\n|\\r|\\b|\\t|\\f|\\u2028|\\u2029|\\x3C)/g, deserializeReplacer);
198
198
  }
199
199
  //#endregion
200
+ //#region src/core/errors.ts
201
+ const { toString: objectToString } = Object.prototype;
202
+ const STEP_ERROR_CODES = {
203
+ parsing: 1,
204
+ serialization: 2,
205
+ deserialization: 3
206
+ };
207
+ function getErrorMessageProd(type) {
208
+ return `Seroval Error (step: ${STEP_ERROR_CODES[type]})`;
209
+ }
210
+ const getErrorMessage = (type, cause) => getErrorMessageProd(type);
211
+ var SerovalError = class extends Error {
212
+ constructor(type, cause) {
213
+ super(getErrorMessage(type, cause));
214
+ this.cause = cause;
215
+ }
216
+ };
217
+ var SerovalParserError = class extends SerovalError {
218
+ constructor(cause) {
219
+ super("parsing", cause);
220
+ }
221
+ };
222
+ var SerovalSerializationError = class extends SerovalError {
223
+ constructor(cause) {
224
+ super("serialization", cause);
225
+ }
226
+ };
227
+ var SerovalDeserializationError = class extends SerovalError {
228
+ constructor(cause) {
229
+ super("deserialization", cause);
230
+ }
231
+ };
232
+ function getSpecificErrorMessage(code) {
233
+ return `Seroval Error (specific: ${code})`;
234
+ }
235
+ var SerovalUnsupportedTypeError = class extends Error {
236
+ constructor(value) {
237
+ super(getSpecificErrorMessage(1));
238
+ this.value = value;
239
+ }
240
+ };
241
+ var SerovalUnsupportedNodeError = class extends Error {
242
+ constructor(node) {
243
+ super(getSpecificErrorMessage(2));
244
+ }
245
+ };
246
+ var SerovalMissingPluginError = class extends Error {
247
+ constructor(tag) {
248
+ super(getSpecificErrorMessage(3));
249
+ }
250
+ };
251
+ var SerovalMissingInstanceError = class extends Error {
252
+ constructor(tag) {
253
+ super(getSpecificErrorMessage(4));
254
+ }
255
+ };
256
+ var SerovalMissingReferenceError = class extends Error {
257
+ constructor(value) {
258
+ super(getSpecificErrorMessage(5));
259
+ this.value = value;
260
+ }
261
+ };
262
+ var SerovalMissingReferenceForIdError = class extends Error {
263
+ constructor(id) {
264
+ super(getSpecificErrorMessage(6));
265
+ }
266
+ };
267
+ var SerovalUnknownTypedArrayError = class extends Error {
268
+ constructor(name) {
269
+ super(getSpecificErrorMessage(7));
270
+ }
271
+ };
272
+ var SerovalMalformedNodeError = class extends Error {
273
+ constructor(node) {
274
+ super(getSpecificErrorMessage(8));
275
+ }
276
+ };
277
+ var SerovalConflictedNodeIdError = class extends Error {
278
+ constructor(node) {
279
+ super(getSpecificErrorMessage(9));
280
+ }
281
+ };
282
+ var SerovalDepthLimitError = class extends Error {
283
+ constructor(limit) {
284
+ super(getSpecificErrorMessage(9));
285
+ }
286
+ };
287
+ //#endregion
200
288
  //#region src/core/keys.ts
201
289
  const REFERENCES_KEY = "__SEROVAL_REFS__";
202
290
  const GLOBAL_CONTEXT_R = `self.\$R`;
@@ -273,14 +361,16 @@ function getErrorOptions(error, features) {
273
361
  const names = Object.getOwnPropertyNames(error);
274
362
  for (let i = 0, len = names.length, name; i < len; i++) {
275
363
  name = names[i];
276
- if (name !== "name" && name !== "message") if (name === "stack") {
277
- if (features & 4) {
364
+ if (name !== "name" && name !== "message") {
365
+ if (name === "stack") {
366
+ if (features & 4) {
367
+ options = options || {};
368
+ options[name] = error[name];
369
+ }
370
+ } else {
278
371
  options = options || {};
279
372
  options[name] = error[name];
280
373
  }
281
- } else {
282
- options = options || {};
283
- options[name] = error[name];
284
374
  }
285
375
  }
286
376
  return options;
@@ -338,13 +428,17 @@ function createArrayNode(id, current, parsedItems) {
338
428
  function createBoxedNode(id, boxed) {
339
429
  return createSerovalNode(21, id, void 0, void 0, void 0, void 0, void 0, void 0, boxed, void 0, void 0, void 0);
340
430
  }
431
+ const MAX_TYPED_ARRAY_LENGTH = 1e6;
341
432
  function createTypedArrayNode(id, current, buffer) {
433
+ if (current.length > MAX_TYPED_ARRAY_LENGTH) throw new SerovalUnsupportedTypeError(current);
342
434
  return createSerovalNode(15, id, void 0, current.constructor.name, void 0, void 0, void 0, void 0, buffer, current.byteOffset, void 0, current.length);
343
435
  }
344
436
  function createBigIntTypedArrayNode(id, current, buffer) {
437
+ if (current.length > MAX_TYPED_ARRAY_LENGTH) throw new SerovalUnsupportedTypeError(current);
345
438
  return createSerovalNode(16, id, void 0, current.constructor.name, void 0, void 0, void 0, void 0, buffer, current.byteOffset, void 0, current.length);
346
439
  }
347
440
  function createDataViewNode(id, current, buffer) {
441
+ if (current.byteLength > MAX_TYPED_ARRAY_LENGTH) throw new SerovalUnsupportedTypeError(current);
348
442
  return createSerovalNode(20, id, void 0, void 0, void 0, void 0, void 0, void 0, buffer, current.byteOffset, void 0, current.byteLength);
349
443
  }
350
444
  function createErrorNode(id, current, options) {
@@ -378,94 +472,6 @@ function createSequenceNode(id, sequence, throwAt, doneAt) {
378
472
  return createSerovalNode(35, id, throwAt, void 0, void 0, void 0, void 0, sequence, void 0, void 0, void 0, doneAt);
379
473
  }
380
474
  //#endregion
381
- //#region src/core/errors.ts
382
- const { toString: objectToString } = Object.prototype;
383
- const STEP_ERROR_CODES = {
384
- parsing: 1,
385
- serialization: 2,
386
- deserialization: 3
387
- };
388
- function getErrorMessageProd(type) {
389
- return `Seroval Error (step: ${STEP_ERROR_CODES[type]})`;
390
- }
391
- const getErrorMessage = (type, cause) => getErrorMessageProd(type);
392
- var SerovalError = class extends Error {
393
- constructor(type, cause) {
394
- super(getErrorMessage(type, cause));
395
- this.cause = cause;
396
- }
397
- };
398
- var SerovalParserError = class extends SerovalError {
399
- constructor(cause) {
400
- super("parsing", cause);
401
- }
402
- };
403
- var SerovalSerializationError = class extends SerovalError {
404
- constructor(cause) {
405
- super("serialization", cause);
406
- }
407
- };
408
- var SerovalDeserializationError = class extends SerovalError {
409
- constructor(cause) {
410
- super("deserialization", cause);
411
- }
412
- };
413
- function getSpecificErrorMessage(code) {
414
- return `Seroval Error (specific: ${code})`;
415
- }
416
- var SerovalUnsupportedTypeError = class extends Error {
417
- constructor(value) {
418
- super(getSpecificErrorMessage(1));
419
- this.value = value;
420
- }
421
- };
422
- var SerovalUnsupportedNodeError = class extends Error {
423
- constructor(node) {
424
- super(getSpecificErrorMessage(2));
425
- }
426
- };
427
- var SerovalMissingPluginError = class extends Error {
428
- constructor(tag) {
429
- super(getSpecificErrorMessage(3));
430
- }
431
- };
432
- var SerovalMissingInstanceError = class extends Error {
433
- constructor(tag) {
434
- super(getSpecificErrorMessage(4));
435
- }
436
- };
437
- var SerovalMissingReferenceError = class extends Error {
438
- constructor(value) {
439
- super(getSpecificErrorMessage(5));
440
- this.value = value;
441
- }
442
- };
443
- var SerovalMissingReferenceForIdError = class extends Error {
444
- constructor(id) {
445
- super(getSpecificErrorMessage(6));
446
- }
447
- };
448
- var SerovalUnknownTypedArrayError = class extends Error {
449
- constructor(name) {
450
- super(getSpecificErrorMessage(7));
451
- }
452
- };
453
- var SerovalMalformedNodeError = class extends Error {
454
- constructor(node) {
455
- super(getSpecificErrorMessage(8));
456
- }
457
- };
458
- var SerovalConflictedNodeIdError = class extends Error {
459
- constructor(node) {
460
- super(getSpecificErrorMessage(9));
461
- }
462
- };
463
- var SerovalDepthLimitError = class extends Error {
464
- constructor(limit) {
465
- super(getSpecificErrorMessage(9));
466
- }
467
- };
468
- //#endregion
469
475
  //#region src/core/opaque-reference.ts
470
476
  /**
471
477
  * An opaque reference allows hiding values from the serializer.
@@ -1053,7 +1059,6 @@ async function parseObjectAsync(ctx, depth, id, current) {
1053
1059
  case DataView: return parseDataView$1(ctx, depth, id, current);
1054
1060
  case Map: return parseMap$1(ctx, depth, id, current);
1055
1061
  case Set: return parseSet$1(ctx, depth, id, current);
1056
- default: break;
1057
1062
  }
1058
1063
  if (currentClass === Promise || current instanceof Promise) return parsePromise$1(ctx, depth, id, current);
1059
1064
  const currentFeatures = ctx.base.features;
@@ -1061,7 +1066,6 @@ async function parseObjectAsync(ctx, depth, id, current) {
1061
1066
  if (currentFeatures & 16) switch (currentClass) {
1062
1067
  case BigInt64Array:
1063
1068
  case BigUint64Array: return parseBigIntTypedArray$1(ctx, depth, id, current);
1064
- default: break;
1065
1069
  }
1066
1070
  if (currentFeatures & 1 && typeof AggregateError !== "undefined" && (currentClass === AggregateError || current instanceof AggregateError)) return parseAggregateError$1(ctx, depth, id, current);
1067
1071
  if (currentFeatures & 64 && typeof Temporal !== "undefined") switch (currentClass) {
@@ -1073,7 +1077,6 @@ async function parseObjectAsync(ctx, depth, id, current) {
1073
1077
  case Temporal.PlainTime: return createTemporalNode(id, 5, current);
1074
1078
  case Temporal.PlainYearMonth: return createTemporalNode(id, 6, current);
1075
1079
  case Temporal.ZonedDateTime: return createTemporalNode(id, 7, current);
1076
- default: break;
1077
1080
  }
1078
1081
  if (current instanceof Error) return parseError$1(ctx, depth, id, current);
1079
1082
  if (SYM_ITERATOR in current || SYM_ASYNC_ITERATOR in current) return parsePlainObject$1(ctx, depth, id, current, !!currentClass);
@@ -1372,15 +1375,17 @@ function deserializeTypedArray(ctx, depth, node) {
1372
1375
  var _node$b;
1373
1376
  const construct = getTypedArrayConstructor(node.c);
1374
1377
  const source = deserialize$1(ctx, depth, node.f);
1378
+ if (!(source instanceof ArrayBuffer)) throw new SerovalMalformedNodeError(node);
1375
1379
  const offset = (_node$b = node.b) !== null && _node$b !== void 0 ? _node$b : 0;
1376
- if (offset < 0 || offset > source.byteLength) throw new SerovalMalformedNodeError(node);
1380
+ if (offset < 0 || offset > source.byteLength || node.l > MAX_BASE64_LENGTH) throw new SerovalMalformedNodeError(node);
1377
1381
  return assignIndexedValue$1(ctx, node.i, new construct(source, offset, node.l));
1378
1382
  }
1379
1383
  function deserializeDataView(ctx, depth, node) {
1380
1384
  var _node$b2;
1381
1385
  const source = deserialize$1(ctx, depth, node.f);
1386
+ if (!(source instanceof ArrayBuffer)) throw new SerovalMalformedNodeError(node);
1382
1387
  const offset = (_node$b2 = node.b) !== null && _node$b2 !== void 0 ? _node$b2 : 0;
1383
- if (offset < 0 || offset > source.byteLength) throw new SerovalMalformedNodeError(node);
1388
+ if (offset < 0 || offset > source.byteLength || node.l > MAX_BASE64_LENGTH) throw new SerovalMalformedNodeError(node);
1384
1389
  return assignIndexedValue$1(ctx, node.i, new DataView(source, offset, node.l));
1385
1390
  }
1386
1391
  function deserializeDictionary(ctx, depth, node, result) {
@@ -1439,11 +1444,15 @@ function deserializePromiseFulfill(ctx, depth, node) {
1439
1444
  }
1440
1445
  function deserializeIteratorFactoryInstance(ctx, depth, node) {
1441
1446
  deserialize$1(ctx, depth, node.a[0]);
1442
- return sequenceToIterator(deserialize$1(ctx, depth, node.a[1]));
1447
+ const source = deserialize$1(ctx, depth, node.a[1]);
1448
+ if (!source || typeof source !== "object" || !isSequence(source)) throw new SerovalMalformedNodeError(node.a[1]);
1449
+ return sequenceToIterator(source);
1443
1450
  }
1444
1451
  function deserializeAsyncIteratorFactoryInstance(ctx, depth, node) {
1445
1452
  deserialize$1(ctx, depth, node.a[0]);
1446
- return streamToAsyncIterable(deserialize$1(ctx, depth, node.a[1]));
1453
+ const source = deserialize$1(ctx, depth, node.a[1]);
1454
+ if (!source || typeof source !== "object" || !isStream(source)) throw new SerovalMalformedNodeError(node.a[1]);
1455
+ return streamToAsyncIterable(source);
1447
1456
  }
1448
1457
  function deserializeStreamConstructor(ctx, depth, node) {
1449
1458
  const result = assignIndexedValue$1(ctx, node.i, createStream());
@@ -1915,9 +1924,10 @@ function serializeStringKeyAssignment(ctx, source, mainAssignments, key, value)
1915
1924
  const serialized = serialize$1(ctx, value);
1916
1925
  const check = Number(key);
1917
1926
  const isIdentifier = check >= 0 && check.toString() === key || isValidIdentifier(key);
1918
- if (isIndexedValueInStack(base, value)) if (isIdentifier && check !== check) createObjectAssign(ctx, source.i, key, serialized);
1919
- else createArrayAssign(ctx, source.i, isIdentifier ? key : "\"" + key + "\"", serialized);
1920
- else {
1927
+ if (isIndexedValueInStack(base, value)) {
1928
+ if (isIdentifier && check !== check) createObjectAssign(ctx, source.i, key, serialized);
1929
+ else createArrayAssign(ctx, source.i, isIdentifier ? key : "\"" + key + "\"", serialized);
1930
+ } else {
1921
1931
  const parentAssignment = base.assignments;
1922
1932
  base.assignments = mainAssignments;
1923
1933
  if (isIdentifier && check !== check) createObjectAssign(ctx, source.i, key, serialized);
@@ -2544,7 +2554,6 @@ function parseObjectPhase2(ctx, depth, id, current, currentClass) {
2544
2554
  case DataView: return parseDataView(ctx, depth, id, current);
2545
2555
  case Map: return parseMap(ctx, depth, id, current);
2546
2556
  case Set: return parseSet(ctx, depth, id, current);
2547
- default: break;
2548
2557
  }
2549
2558
  if (currentClass === Promise || current instanceof Promise) return parsePromise(ctx, depth, id, current);
2550
2559
  const currentFeatures = ctx.base.features;
@@ -2552,7 +2561,6 @@ function parseObjectPhase2(ctx, depth, id, current, currentClass) {
2552
2561
  if (currentFeatures & 16) switch (currentClass) {
2553
2562
  case BigInt64Array:
2554
2563
  case BigUint64Array: return parseBigIntTypedArray(ctx, depth, id, current);
2555
- default: break;
2556
2564
  }
2557
2565
  if (currentFeatures & 1 && typeof AggregateError !== "undefined" && (currentClass === AggregateError || current instanceof AggregateError)) return parseAggregateError(ctx, depth, id, current);
2558
2566
  if (currentFeatures & 64 && typeof Temporal !== "undefined") switch (currentClass) {
@@ -2564,7 +2572,6 @@ function parseObjectPhase2(ctx, depth, id, current, currentClass) {
2564
2572
  case Temporal.PlainTime: return createTemporalNode(id, 5, current);
2565
2573
  case Temporal.PlainYearMonth: return createTemporalNode(id, 6, current);
2566
2574
  case Temporal.ZonedDateTime: return createTemporalNode(id, 7, current);
2567
- default: break;
2568
2575
  }
2569
2576
  if (current instanceof Error) return parseError(ctx, depth, id, current);
2570
2577
  if (SYM_ITERATOR in current || SYM_ASYNC_ITERATOR in current) return parsePlainObject(ctx, depth, id, current, !!currentClass);
package/dist/index.js CHANGED
@@ -196,6 +196,94 @@ function deserializeString(str) {
196
196
  return str.replace(/(\\\\|\\"|\\n|\\r|\\b|\\t|\\f|\\u2028|\\u2029|\\x3C)/g, deserializeReplacer);
197
197
  }
198
198
  //#endregion
199
+ //#region src/core/errors.ts
200
+ const { toString: objectToString } = Object.prototype;
201
+ const STEP_ERROR_CODES = {
202
+ parsing: 1,
203
+ serialization: 2,
204
+ deserialization: 3
205
+ };
206
+ function getErrorMessageProd(type) {
207
+ return `Seroval Error (step: ${STEP_ERROR_CODES[type]})`;
208
+ }
209
+ const getErrorMessage = (type, cause) => getErrorMessageProd(type);
210
+ var SerovalError = class extends Error {
211
+ constructor(type, cause) {
212
+ super(getErrorMessage(type, cause));
213
+ this.cause = cause;
214
+ }
215
+ };
216
+ var SerovalParserError = class extends SerovalError {
217
+ constructor(cause) {
218
+ super("parsing", cause);
219
+ }
220
+ };
221
+ var SerovalSerializationError = class extends SerovalError {
222
+ constructor(cause) {
223
+ super("serialization", cause);
224
+ }
225
+ };
226
+ var SerovalDeserializationError = class extends SerovalError {
227
+ constructor(cause) {
228
+ super("deserialization", cause);
229
+ }
230
+ };
231
+ function getSpecificErrorMessage(code) {
232
+ return `Seroval Error (specific: ${code})`;
233
+ }
234
+ var SerovalUnsupportedTypeError = class extends Error {
235
+ constructor(value) {
236
+ super(getSpecificErrorMessage(1));
237
+ this.value = value;
238
+ }
239
+ };
240
+ var SerovalUnsupportedNodeError = class extends Error {
241
+ constructor(node) {
242
+ super(getSpecificErrorMessage(2));
243
+ }
244
+ };
245
+ var SerovalMissingPluginError = class extends Error {
246
+ constructor(tag) {
247
+ super(getSpecificErrorMessage(3));
248
+ }
249
+ };
250
+ var SerovalMissingInstanceError = class extends Error {
251
+ constructor(tag) {
252
+ super(getSpecificErrorMessage(4));
253
+ }
254
+ };
255
+ var SerovalMissingReferenceError = class extends Error {
256
+ constructor(value) {
257
+ super(getSpecificErrorMessage(5));
258
+ this.value = value;
259
+ }
260
+ };
261
+ var SerovalMissingReferenceForIdError = class extends Error {
262
+ constructor(id) {
263
+ super(getSpecificErrorMessage(6));
264
+ }
265
+ };
266
+ var SerovalUnknownTypedArrayError = class extends Error {
267
+ constructor(name) {
268
+ super(getSpecificErrorMessage(7));
269
+ }
270
+ };
271
+ var SerovalMalformedNodeError = class extends Error {
272
+ constructor(node) {
273
+ super(getSpecificErrorMessage(8));
274
+ }
275
+ };
276
+ var SerovalConflictedNodeIdError = class extends Error {
277
+ constructor(node) {
278
+ super(getSpecificErrorMessage(9));
279
+ }
280
+ };
281
+ var SerovalDepthLimitError = class extends Error {
282
+ constructor(limit) {
283
+ super(getSpecificErrorMessage(9));
284
+ }
285
+ };
286
+ //#endregion
199
287
  //#region src/core/keys.ts
200
288
  const REFERENCES_KEY = "__SEROVAL_REFS__";
201
289
  const GLOBAL_CONTEXT_R = `self.\$R`;
@@ -272,14 +360,16 @@ function getErrorOptions(error, features) {
272
360
  const names = Object.getOwnPropertyNames(error);
273
361
  for (let i = 0, len = names.length, name; i < len; i++) {
274
362
  name = names[i];
275
- if (name !== "name" && name !== "message") if (name === "stack") {
276
- if (features & 4) {
363
+ if (name !== "name" && name !== "message") {
364
+ if (name === "stack") {
365
+ if (features & 4) {
366
+ options = options || {};
367
+ options[name] = error[name];
368
+ }
369
+ } else {
277
370
  options = options || {};
278
371
  options[name] = error[name];
279
372
  }
280
- } else {
281
- options = options || {};
282
- options[name] = error[name];
283
373
  }
284
374
  }
285
375
  return options;
@@ -337,13 +427,17 @@ function createArrayNode(id, current, parsedItems) {
337
427
  function createBoxedNode(id, boxed) {
338
428
  return createSerovalNode(21, id, void 0, void 0, void 0, void 0, void 0, void 0, boxed, void 0, void 0, void 0);
339
429
  }
430
+ const MAX_TYPED_ARRAY_LENGTH = 1e6;
340
431
  function createTypedArrayNode(id, current, buffer) {
432
+ if (current.length > MAX_TYPED_ARRAY_LENGTH) throw new SerovalUnsupportedTypeError(current);
341
433
  return createSerovalNode(15, id, void 0, current.constructor.name, void 0, void 0, void 0, void 0, buffer, current.byteOffset, void 0, current.length);
342
434
  }
343
435
  function createBigIntTypedArrayNode(id, current, buffer) {
436
+ if (current.length > MAX_TYPED_ARRAY_LENGTH) throw new SerovalUnsupportedTypeError(current);
344
437
  return createSerovalNode(16, id, void 0, current.constructor.name, void 0, void 0, void 0, void 0, buffer, current.byteOffset, void 0, current.length);
345
438
  }
346
439
  function createDataViewNode(id, current, buffer) {
440
+ if (current.byteLength > MAX_TYPED_ARRAY_LENGTH) throw new SerovalUnsupportedTypeError(current);
347
441
  return createSerovalNode(20, id, void 0, void 0, void 0, void 0, void 0, void 0, buffer, current.byteOffset, void 0, current.byteLength);
348
442
  }
349
443
  function createErrorNode(id, current, options) {
@@ -377,94 +471,6 @@ function createSequenceNode(id, sequence, throwAt, doneAt) {
377
471
  return createSerovalNode(35, id, throwAt, void 0, void 0, void 0, void 0, sequence, void 0, void 0, void 0, doneAt);
378
472
  }
379
473
  //#endregion
380
- //#region src/core/errors.ts
381
- const { toString: objectToString } = Object.prototype;
382
- const STEP_ERROR_CODES = {
383
- parsing: 1,
384
- serialization: 2,
385
- deserialization: 3
386
- };
387
- function getErrorMessageProd(type) {
388
- return `Seroval Error (step: ${STEP_ERROR_CODES[type]})`;
389
- }
390
- const getErrorMessage = (type, cause) => getErrorMessageProd(type);
391
- var SerovalError = class extends Error {
392
- constructor(type, cause) {
393
- super(getErrorMessage(type, cause));
394
- this.cause = cause;
395
- }
396
- };
397
- var SerovalParserError = class extends SerovalError {
398
- constructor(cause) {
399
- super("parsing", cause);
400
- }
401
- };
402
- var SerovalSerializationError = class extends SerovalError {
403
- constructor(cause) {
404
- super("serialization", cause);
405
- }
406
- };
407
- var SerovalDeserializationError = class extends SerovalError {
408
- constructor(cause) {
409
- super("deserialization", cause);
410
- }
411
- };
412
- function getSpecificErrorMessage(code) {
413
- return `Seroval Error (specific: ${code})`;
414
- }
415
- var SerovalUnsupportedTypeError = class extends Error {
416
- constructor(value) {
417
- super(getSpecificErrorMessage(1));
418
- this.value = value;
419
- }
420
- };
421
- var SerovalUnsupportedNodeError = class extends Error {
422
- constructor(node) {
423
- super(getSpecificErrorMessage(2));
424
- }
425
- };
426
- var SerovalMissingPluginError = class extends Error {
427
- constructor(tag) {
428
- super(getSpecificErrorMessage(3));
429
- }
430
- };
431
- var SerovalMissingInstanceError = class extends Error {
432
- constructor(tag) {
433
- super(getSpecificErrorMessage(4));
434
- }
435
- };
436
- var SerovalMissingReferenceError = class extends Error {
437
- constructor(value) {
438
- super(getSpecificErrorMessage(5));
439
- this.value = value;
440
- }
441
- };
442
- var SerovalMissingReferenceForIdError = class extends Error {
443
- constructor(id) {
444
- super(getSpecificErrorMessage(6));
445
- }
446
- };
447
- var SerovalUnknownTypedArrayError = class extends Error {
448
- constructor(name) {
449
- super(getSpecificErrorMessage(7));
450
- }
451
- };
452
- var SerovalMalformedNodeError = class extends Error {
453
- constructor(node) {
454
- super(getSpecificErrorMessage(8));
455
- }
456
- };
457
- var SerovalConflictedNodeIdError = class extends Error {
458
- constructor(node) {
459
- super(getSpecificErrorMessage(9));
460
- }
461
- };
462
- var SerovalDepthLimitError = class extends Error {
463
- constructor(limit) {
464
- super(getSpecificErrorMessage(9));
465
- }
466
- };
467
- //#endregion
468
474
  //#region src/core/opaque-reference.ts
469
475
  /**
470
476
  * An opaque reference allows hiding values from the serializer.
@@ -1052,7 +1058,6 @@ async function parseObjectAsync(ctx, depth, id, current) {
1052
1058
  case DataView: return parseDataView$1(ctx, depth, id, current);
1053
1059
  case Map: return parseMap$1(ctx, depth, id, current);
1054
1060
  case Set: return parseSet$1(ctx, depth, id, current);
1055
- default: break;
1056
1061
  }
1057
1062
  if (currentClass === Promise || current instanceof Promise) return parsePromise$1(ctx, depth, id, current);
1058
1063
  const currentFeatures = ctx.base.features;
@@ -1060,7 +1065,6 @@ async function parseObjectAsync(ctx, depth, id, current) {
1060
1065
  if (currentFeatures & 16) switch (currentClass) {
1061
1066
  case BigInt64Array:
1062
1067
  case BigUint64Array: return parseBigIntTypedArray$1(ctx, depth, id, current);
1063
- default: break;
1064
1068
  }
1065
1069
  if (currentFeatures & 1 && typeof AggregateError !== "undefined" && (currentClass === AggregateError || current instanceof AggregateError)) return parseAggregateError$1(ctx, depth, id, current);
1066
1070
  if (currentFeatures & 64 && typeof Temporal !== "undefined") switch (currentClass) {
@@ -1072,7 +1076,6 @@ async function parseObjectAsync(ctx, depth, id, current) {
1072
1076
  case Temporal.PlainTime: return createTemporalNode(id, 5, current);
1073
1077
  case Temporal.PlainYearMonth: return createTemporalNode(id, 6, current);
1074
1078
  case Temporal.ZonedDateTime: return createTemporalNode(id, 7, current);
1075
- default: break;
1076
1079
  }
1077
1080
  if (current instanceof Error) return parseError$1(ctx, depth, id, current);
1078
1081
  if (SYM_ITERATOR in current || SYM_ASYNC_ITERATOR in current) return parsePlainObject$1(ctx, depth, id, current, !!currentClass);
@@ -1371,15 +1374,17 @@ function deserializeTypedArray(ctx, depth, node) {
1371
1374
  var _node$b;
1372
1375
  const construct = getTypedArrayConstructor(node.c);
1373
1376
  const source = deserialize$1(ctx, depth, node.f);
1377
+ if (!(source instanceof ArrayBuffer)) throw new SerovalMalformedNodeError(node);
1374
1378
  const offset = (_node$b = node.b) !== null && _node$b !== void 0 ? _node$b : 0;
1375
- if (offset < 0 || offset > source.byteLength) throw new SerovalMalformedNodeError(node);
1379
+ if (offset < 0 || offset > source.byteLength || node.l > MAX_BASE64_LENGTH) throw new SerovalMalformedNodeError(node);
1376
1380
  return assignIndexedValue$1(ctx, node.i, new construct(source, offset, node.l));
1377
1381
  }
1378
1382
  function deserializeDataView(ctx, depth, node) {
1379
1383
  var _node$b2;
1380
1384
  const source = deserialize$1(ctx, depth, node.f);
1385
+ if (!(source instanceof ArrayBuffer)) throw new SerovalMalformedNodeError(node);
1381
1386
  const offset = (_node$b2 = node.b) !== null && _node$b2 !== void 0 ? _node$b2 : 0;
1382
- if (offset < 0 || offset > source.byteLength) throw new SerovalMalformedNodeError(node);
1387
+ if (offset < 0 || offset > source.byteLength || node.l > MAX_BASE64_LENGTH) throw new SerovalMalformedNodeError(node);
1383
1388
  return assignIndexedValue$1(ctx, node.i, new DataView(source, offset, node.l));
1384
1389
  }
1385
1390
  function deserializeDictionary(ctx, depth, node, result) {
@@ -1438,11 +1443,15 @@ function deserializePromiseFulfill(ctx, depth, node) {
1438
1443
  }
1439
1444
  function deserializeIteratorFactoryInstance(ctx, depth, node) {
1440
1445
  deserialize$1(ctx, depth, node.a[0]);
1441
- return sequenceToIterator(deserialize$1(ctx, depth, node.a[1]));
1446
+ const source = deserialize$1(ctx, depth, node.a[1]);
1447
+ if (!source || typeof source !== "object" || !isSequence(source)) throw new SerovalMalformedNodeError(node.a[1]);
1448
+ return sequenceToIterator(source);
1442
1449
  }
1443
1450
  function deserializeAsyncIteratorFactoryInstance(ctx, depth, node) {
1444
1451
  deserialize$1(ctx, depth, node.a[0]);
1445
- return streamToAsyncIterable(deserialize$1(ctx, depth, node.a[1]));
1452
+ const source = deserialize$1(ctx, depth, node.a[1]);
1453
+ if (!source || typeof source !== "object" || !isStream(source)) throw new SerovalMalformedNodeError(node.a[1]);
1454
+ return streamToAsyncIterable(source);
1446
1455
  }
1447
1456
  function deserializeStreamConstructor(ctx, depth, node) {
1448
1457
  const result = assignIndexedValue$1(ctx, node.i, createStream());
@@ -1914,9 +1923,10 @@ function serializeStringKeyAssignment(ctx, source, mainAssignments, key, value)
1914
1923
  const serialized = serialize$1(ctx, value);
1915
1924
  const check = Number(key);
1916
1925
  const isIdentifier = check >= 0 && check.toString() === key || isValidIdentifier(key);
1917
- if (isIndexedValueInStack(base, value)) if (isIdentifier && check !== check) createObjectAssign(ctx, source.i, key, serialized);
1918
- else createArrayAssign(ctx, source.i, isIdentifier ? key : "\"" + key + "\"", serialized);
1919
- else {
1926
+ if (isIndexedValueInStack(base, value)) {
1927
+ if (isIdentifier && check !== check) createObjectAssign(ctx, source.i, key, serialized);
1928
+ else createArrayAssign(ctx, source.i, isIdentifier ? key : "\"" + key + "\"", serialized);
1929
+ } else {
1920
1930
  const parentAssignment = base.assignments;
1921
1931
  base.assignments = mainAssignments;
1922
1932
  if (isIdentifier && check !== check) createObjectAssign(ctx, source.i, key, serialized);
@@ -2543,7 +2553,6 @@ function parseObjectPhase2(ctx, depth, id, current, currentClass) {
2543
2553
  case DataView: return parseDataView(ctx, depth, id, current);
2544
2554
  case Map: return parseMap(ctx, depth, id, current);
2545
2555
  case Set: return parseSet(ctx, depth, id, current);
2546
- default: break;
2547
2556
  }
2548
2557
  if (currentClass === Promise || current instanceof Promise) return parsePromise(ctx, depth, id, current);
2549
2558
  const currentFeatures = ctx.base.features;
@@ -2551,7 +2560,6 @@ function parseObjectPhase2(ctx, depth, id, current, currentClass) {
2551
2560
  if (currentFeatures & 16) switch (currentClass) {
2552
2561
  case BigInt64Array:
2553
2562
  case BigUint64Array: return parseBigIntTypedArray(ctx, depth, id, current);
2554
- default: break;
2555
2563
  }
2556
2564
  if (currentFeatures & 1 && typeof AggregateError !== "undefined" && (currentClass === AggregateError || current instanceof AggregateError)) return parseAggregateError(ctx, depth, id, current);
2557
2565
  if (currentFeatures & 64 && typeof Temporal !== "undefined") switch (currentClass) {
@@ -2563,7 +2571,6 @@ function parseObjectPhase2(ctx, depth, id, current, currentClass) {
2563
2571
  case Temporal.PlainTime: return createTemporalNode(id, 5, current);
2564
2572
  case Temporal.PlainYearMonth: return createTemporalNode(id, 6, current);
2565
2573
  case Temporal.ZonedDateTime: return createTemporalNode(id, 7, current);
2566
- default: break;
2567
2574
  }
2568
2575
  if (current instanceof Error) return parseError(ctx, depth, id, current);
2569
2576
  if (SYM_ITERATOR in current || SYM_ASYNC_ITERATOR in current) return parsePlainObject(ctx, depth, id, current, !!currentClass);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "seroval",
3
3
  "type": "module",
4
- "version": "1.6.2",
4
+ "version": "1.6.4",
5
5
  "files": [
6
6
  "dist"
7
7
  ],
@@ -16,15 +16,15 @@
16
16
  "serialization"
17
17
  ],
18
18
  "devDependencies": {
19
- "@types/node": "^24.10.0",
20
- "@vitest/ui": "^4.0.6",
21
- "esbuild": "^0.28.1",
22
- "temporal-polyfill": "^0.3.2",
19
+ "@types/node": "^26.2.0",
20
+ "@vitest/ui": "^4.1.10",
21
+ "esbuild": "^0.28.2",
22
+ "temporal-polyfill": "^1.0.4",
23
23
  "ts-prune": "^0.10.3",
24
24
  "tsdown": "^0.22.14",
25
25
  "tslib": "^2.8.1",
26
26
  "typescript": "^7.0.2",
27
- "vitest": "^4.0.6"
27
+ "vitest": "^4.1.10"
28
28
  },
29
29
  "private": false,
30
30
  "description": "Stringify JS values",