seroval 1.6.2 → 1.6.3

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);
@@ -1380,14 +1383,14 @@ function deserializeTypedArray(ctx, depth, node) {
1380
1383
  const construct = getTypedArrayConstructor(node.c);
1381
1384
  const source = deserialize$1(ctx, depth, node.f);
1382
1385
  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);
1386
+ if (offset < 0 || offset > source.byteLength || node.l > MAX_BASE64_LENGTH) throw new SerovalMalformedNodeError(node);
1384
1387
  return assignIndexedValue$1(ctx, node.i, new construct(source, offset, node.l));
1385
1388
  }
1386
1389
  function deserializeDataView(ctx, depth, node) {
1387
1390
  var _node$b2;
1388
1391
  const source = deserialize$1(ctx, depth, node.f);
1389
1392
  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);
1393
+ if (offset < 0 || offset > source.byteLength || node.l > MAX_BASE64_LENGTH) throw new SerovalMalformedNodeError(node);
1391
1394
  return assignIndexedValue$1(ctx, node.i, new DataView(source, offset, node.l));
1392
1395
  }
1393
1396
  function deserializeDictionary(ctx, depth, node, result) {
@@ -1922,9 +1925,10 @@ function serializeStringKeyAssignment(ctx, source, mainAssignments, key, value)
1922
1925
  const serialized = serialize$1(ctx, value);
1923
1926
  const check = Number(key);
1924
1927
  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 {
1928
+ if (isIndexedValueInStack(base, value)) {
1929
+ if (isIdentifier && check !== check) createObjectAssign(ctx, source.i, key, serialized);
1930
+ else createArrayAssign(ctx, source.i, isIdentifier ? key : "\"" + key + "\"", serialized);
1931
+ } else {
1928
1932
  const parentAssignment = base.assignments;
1929
1933
  base.assignments = mainAssignments;
1930
1934
  if (isIdentifier && check !== check) createObjectAssign(ctx, source.i, key, serialized);
@@ -2551,7 +2555,6 @@ function parseObjectPhase2(ctx, depth, id, current, currentClass) {
2551
2555
  case DataView: return parseDataView(ctx, depth, id, current);
2552
2556
  case Map: return parseMap(ctx, depth, id, current);
2553
2557
  case Set: return parseSet(ctx, depth, id, current);
2554
- default: break;
2555
2558
  }
2556
2559
  if (currentClass === Promise || current instanceof Promise) return parsePromise(ctx, depth, id, current);
2557
2560
  const currentFeatures = ctx.base.features;
@@ -2559,7 +2562,6 @@ function parseObjectPhase2(ctx, depth, id, current, currentClass) {
2559
2562
  if (currentFeatures & 16) switch (currentClass) {
2560
2563
  case BigInt64Array:
2561
2564
  case BigUint64Array: return parseBigIntTypedArray(ctx, depth, id, current);
2562
- default: break;
2563
2565
  }
2564
2566
  if (currentFeatures & 1 && typeof AggregateError !== "undefined" && (currentClass === AggregateError || current instanceof AggregateError)) return parseAggregateError(ctx, depth, id, current);
2565
2567
  if (currentFeatures & 64 && typeof Temporal !== "undefined") switch (currentClass) {
@@ -2571,7 +2573,6 @@ function parseObjectPhase2(ctx, depth, id, current, currentClass) {
2571
2573
  case Temporal.PlainTime: return createTemporalNode(id, 5, current);
2572
2574
  case Temporal.PlainYearMonth: return createTemporalNode(id, 6, current);
2573
2575
  case Temporal.ZonedDateTime: return createTemporalNode(id, 7, current);
2574
- default: break;
2575
2576
  }
2576
2577
  if (current instanceof Error) return parseError(ctx, depth, id, current);
2577
2578
  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);
@@ -1379,14 +1382,14 @@ function deserializeTypedArray(ctx, depth, node) {
1379
1382
  const construct = getTypedArrayConstructor(node.c);
1380
1383
  const source = deserialize$1(ctx, depth, node.f);
1381
1384
  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);
1385
+ if (offset < 0 || offset > source.byteLength || node.l > MAX_BASE64_LENGTH) throw new SerovalMalformedNodeError(node);
1383
1386
  return assignIndexedValue$1(ctx, node.i, new construct(source, offset, node.l));
1384
1387
  }
1385
1388
  function deserializeDataView(ctx, depth, node) {
1386
1389
  var _node$b2;
1387
1390
  const source = deserialize$1(ctx, depth, node.f);
1388
1391
  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);
1392
+ if (offset < 0 || offset > source.byteLength || node.l > MAX_BASE64_LENGTH) throw new SerovalMalformedNodeError(node);
1390
1393
  return assignIndexedValue$1(ctx, node.i, new DataView(source, offset, node.l));
1391
1394
  }
1392
1395
  function deserializeDictionary(ctx, depth, node, result) {
@@ -1921,9 +1924,10 @@ function serializeStringKeyAssignment(ctx, source, mainAssignments, key, value)
1921
1924
  const serialized = serialize$1(ctx, value);
1922
1925
  const check = Number(key);
1923
1926
  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 {
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 {
1927
1931
  const parentAssignment = base.assignments;
1928
1932
  base.assignments = mainAssignments;
1929
1933
  if (isIdentifier && check !== check) createObjectAssign(ctx, source.i, key, serialized);
@@ -2550,7 +2554,6 @@ function parseObjectPhase2(ctx, depth, id, current, currentClass) {
2550
2554
  case DataView: return parseDataView(ctx, depth, id, current);
2551
2555
  case Map: return parseMap(ctx, depth, id, current);
2552
2556
  case Set: return parseSet(ctx, depth, id, current);
2553
- default: break;
2554
2557
  }
2555
2558
  if (currentClass === Promise || current instanceof Promise) return parsePromise(ctx, depth, id, current);
2556
2559
  const currentFeatures = ctx.base.features;
@@ -2558,7 +2561,6 @@ function parseObjectPhase2(ctx, depth, id, current, currentClass) {
2558
2561
  if (currentFeatures & 16) switch (currentClass) {
2559
2562
  case BigInt64Array:
2560
2563
  case BigUint64Array: return parseBigIntTypedArray(ctx, depth, id, current);
2561
- default: break;
2562
2564
  }
2563
2565
  if (currentFeatures & 1 && typeof AggregateError !== "undefined" && (currentClass === AggregateError || current instanceof AggregateError)) return parseAggregateError(ctx, depth, id, current);
2564
2566
  if (currentFeatures & 64 && typeof Temporal !== "undefined") switch (currentClass) {
@@ -2570,7 +2572,6 @@ function parseObjectPhase2(ctx, depth, id, current, currentClass) {
2570
2572
  case Temporal.PlainTime: return createTemporalNode(id, 5, current);
2571
2573
  case Temporal.PlainYearMonth: return createTemporalNode(id, 6, current);
2572
2574
  case Temporal.ZonedDateTime: return createTemporalNode(id, 7, current);
2573
- default: break;
2574
2575
  }
2575
2576
  if (current instanceof Error) return parseError(ctx, depth, id, current);
2576
2577
  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);
@@ -1373,14 +1376,14 @@ function deserializeTypedArray(ctx, depth, node) {
1373
1376
  const construct = getTypedArrayConstructor(node.c);
1374
1377
  const source = deserialize$1(ctx, depth, node.f);
1375
1378
  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);
1379
+ if (offset < 0 || offset > source.byteLength || node.l > MAX_BASE64_LENGTH) throw new SerovalMalformedNodeError(node);
1377
1380
  return assignIndexedValue$1(ctx, node.i, new construct(source, offset, node.l));
1378
1381
  }
1379
1382
  function deserializeDataView(ctx, depth, node) {
1380
1383
  var _node$b2;
1381
1384
  const source = deserialize$1(ctx, depth, node.f);
1382
1385
  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);
1386
+ if (offset < 0 || offset > source.byteLength || node.l > MAX_BASE64_LENGTH) throw new SerovalMalformedNodeError(node);
1384
1387
  return assignIndexedValue$1(ctx, node.i, new DataView(source, offset, node.l));
1385
1388
  }
1386
1389
  function deserializeDictionary(ctx, depth, node, result) {
@@ -1915,9 +1918,10 @@ function serializeStringKeyAssignment(ctx, source, mainAssignments, key, value)
1915
1918
  const serialized = serialize$1(ctx, value);
1916
1919
  const check = Number(key);
1917
1920
  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 {
1921
+ if (isIndexedValueInStack(base, value)) {
1922
+ if (isIdentifier && check !== check) createObjectAssign(ctx, source.i, key, serialized);
1923
+ else createArrayAssign(ctx, source.i, isIdentifier ? key : "\"" + key + "\"", serialized);
1924
+ } else {
1921
1925
  const parentAssignment = base.assignments;
1922
1926
  base.assignments = mainAssignments;
1923
1927
  if (isIdentifier && check !== check) createObjectAssign(ctx, source.i, key, serialized);
@@ -2544,7 +2548,6 @@ function parseObjectPhase2(ctx, depth, id, current, currentClass) {
2544
2548
  case DataView: return parseDataView(ctx, depth, id, current);
2545
2549
  case Map: return parseMap(ctx, depth, id, current);
2546
2550
  case Set: return parseSet(ctx, depth, id, current);
2547
- default: break;
2548
2551
  }
2549
2552
  if (currentClass === Promise || current instanceof Promise) return parsePromise(ctx, depth, id, current);
2550
2553
  const currentFeatures = ctx.base.features;
@@ -2552,7 +2555,6 @@ function parseObjectPhase2(ctx, depth, id, current, currentClass) {
2552
2555
  if (currentFeatures & 16) switch (currentClass) {
2553
2556
  case BigInt64Array:
2554
2557
  case BigUint64Array: return parseBigIntTypedArray(ctx, depth, id, current);
2555
- default: break;
2556
2558
  }
2557
2559
  if (currentFeatures & 1 && typeof AggregateError !== "undefined" && (currentClass === AggregateError || current instanceof AggregateError)) return parseAggregateError(ctx, depth, id, current);
2558
2560
  if (currentFeatures & 64 && typeof Temporal !== "undefined") switch (currentClass) {
@@ -2564,7 +2566,6 @@ function parseObjectPhase2(ctx, depth, id, current, currentClass) {
2564
2566
  case Temporal.PlainTime: return createTemporalNode(id, 5, current);
2565
2567
  case Temporal.PlainYearMonth: return createTemporalNode(id, 6, current);
2566
2568
  case Temporal.ZonedDateTime: return createTemporalNode(id, 7, current);
2567
- default: break;
2568
2569
  }
2569
2570
  if (current instanceof Error) return parseError(ctx, depth, id, current);
2570
2571
  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);
@@ -1372,14 +1375,14 @@ function deserializeTypedArray(ctx, depth, node) {
1372
1375
  const construct = getTypedArrayConstructor(node.c);
1373
1376
  const source = deserialize$1(ctx, depth, node.f);
1374
1377
  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);
1378
+ if (offset < 0 || offset > source.byteLength || node.l > MAX_BASE64_LENGTH) throw new SerovalMalformedNodeError(node);
1376
1379
  return assignIndexedValue$1(ctx, node.i, new construct(source, offset, node.l));
1377
1380
  }
1378
1381
  function deserializeDataView(ctx, depth, node) {
1379
1382
  var _node$b2;
1380
1383
  const source = deserialize$1(ctx, depth, node.f);
1381
1384
  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);
1385
+ if (offset < 0 || offset > source.byteLength || node.l > MAX_BASE64_LENGTH) throw new SerovalMalformedNodeError(node);
1383
1386
  return assignIndexedValue$1(ctx, node.i, new DataView(source, offset, node.l));
1384
1387
  }
1385
1388
  function deserializeDictionary(ctx, depth, node, result) {
@@ -1914,9 +1917,10 @@ function serializeStringKeyAssignment(ctx, source, mainAssignments, key, value)
1914
1917
  const serialized = serialize$1(ctx, value);
1915
1918
  const check = Number(key);
1916
1919
  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 {
1920
+ if (isIndexedValueInStack(base, value)) {
1921
+ if (isIdentifier && check !== check) createObjectAssign(ctx, source.i, key, serialized);
1922
+ else createArrayAssign(ctx, source.i, isIdentifier ? key : "\"" + key + "\"", serialized);
1923
+ } else {
1920
1924
  const parentAssignment = base.assignments;
1921
1925
  base.assignments = mainAssignments;
1922
1926
  if (isIdentifier && check !== check) createObjectAssign(ctx, source.i, key, serialized);
@@ -2543,7 +2547,6 @@ function parseObjectPhase2(ctx, depth, id, current, currentClass) {
2543
2547
  case DataView: return parseDataView(ctx, depth, id, current);
2544
2548
  case Map: return parseMap(ctx, depth, id, current);
2545
2549
  case Set: return parseSet(ctx, depth, id, current);
2546
- default: break;
2547
2550
  }
2548
2551
  if (currentClass === Promise || current instanceof Promise) return parsePromise(ctx, depth, id, current);
2549
2552
  const currentFeatures = ctx.base.features;
@@ -2551,7 +2554,6 @@ function parseObjectPhase2(ctx, depth, id, current, currentClass) {
2551
2554
  if (currentFeatures & 16) switch (currentClass) {
2552
2555
  case BigInt64Array:
2553
2556
  case BigUint64Array: return parseBigIntTypedArray(ctx, depth, id, current);
2554
- default: break;
2555
2557
  }
2556
2558
  if (currentFeatures & 1 && typeof AggregateError !== "undefined" && (currentClass === AggregateError || current instanceof AggregateError)) return parseAggregateError(ctx, depth, id, current);
2557
2559
  if (currentFeatures & 64 && typeof Temporal !== "undefined") switch (currentClass) {
@@ -2563,7 +2565,6 @@ function parseObjectPhase2(ctx, depth, id, current, currentClass) {
2563
2565
  case Temporal.PlainTime: return createTemporalNode(id, 5, current);
2564
2566
  case Temporal.PlainYearMonth: return createTemporalNode(id, 6, current);
2565
2567
  case Temporal.ZonedDateTime: return createTemporalNode(id, 7, current);
2566
- default: break;
2567
2568
  }
2568
2569
  if (current instanceof Error) return parseError(ctx, depth, id, current);
2569
2570
  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.3",
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.3",
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",