seroval 1.6.1 → 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.
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);
@@ -1236,6 +1239,9 @@ function guardIndexedValue(ctx, id) {
1236
1239
  });
1237
1240
  if (ctx.refs.has(id)) throw new Error("Conflicted ref id: " + id);
1238
1241
  }
1242
+ function isThennable(value) {
1243
+ return !!value && typeof value === "object" && "then" in value && typeof value.then === "function";
1244
+ }
1239
1245
  function assignIndexedValueVanilla(ctx, id, value) {
1240
1246
  guardIndexedValue(ctx.base, id);
1241
1247
  if (ctx.state.marked.has(id)) ctx.base.refs.set(id, value);
@@ -1370,14 +1376,14 @@ function deserializeTypedArray(ctx, depth, node) {
1370
1376
  const construct = getTypedArrayConstructor(node.c);
1371
1377
  const source = deserialize$1(ctx, depth, node.f);
1372
1378
  const offset = (_node$b = node.b) !== null && _node$b !== void 0 ? _node$b : 0;
1373
- 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);
1374
1380
  return assignIndexedValue$1(ctx, node.i, new construct(source, offset, node.l));
1375
1381
  }
1376
1382
  function deserializeDataView(ctx, depth, node) {
1377
1383
  var _node$b2;
1378
1384
  const source = deserialize$1(ctx, depth, node.f);
1379
1385
  const offset = (_node$b2 = node.b) !== null && _node$b2 !== void 0 ? _node$b2 : 0;
1380
- 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);
1381
1387
  return assignIndexedValue$1(ctx, node.i, new DataView(source, offset, node.l));
1382
1388
  }
1383
1389
  function deserializeDictionary(ctx, depth, node, result) {
@@ -1398,6 +1404,7 @@ function deserializePromise(ctx, depth, node) {
1398
1404
  const deferred = PROMISE_CONSTRUCTOR();
1399
1405
  const result = assignIndexedValue$1(ctx, node.i, deferred.p);
1400
1406
  const deserialized = deserialize$1(ctx, depth, node.f);
1407
+ if (isThennable(deserialized)) throw new SerovalMalformedNodeError(node.f);
1401
1408
  if (node.s) deferred.s(deserialized);
1402
1409
  else deferred.f(deserialized);
1403
1410
  return result;
@@ -1421,20 +1428,14 @@ function deserializePromiseConstructor(ctx, node) {
1421
1428
  assignNodeType(ctx, node.s, 22);
1422
1429
  return value;
1423
1430
  }
1424
- function deserializePromiseResolve(ctx, depth, node) {
1431
+ function deserializePromiseFulfill(ctx, depth, node) {
1425
1432
  const deferred = ctx.base.refs.get(node.i);
1426
1433
  if (deferred) {
1427
1434
  validateNodeType(ctx, node, node.i, 22);
1428
- deferred.s(deserialize$1(ctx, depth, node.a[1]));
1429
- return;
1430
- }
1431
- throw new SerovalMissingInstanceError("Promise");
1432
- }
1433
- function deserializePromiseReject(ctx, depth, node) {
1434
- const deferred = ctx.base.refs.get(node.i);
1435
- if (deferred) {
1436
- validateNodeType(ctx, node, node.i, 22);
1437
- deferred.f(deserialize$1(ctx, depth, node.a[1]));
1435
+ const deserialized = deserialize$1(ctx, depth, node.a[1]);
1436
+ if (isThennable(deserialized)) throw new SerovalMalformedNodeError(node.a[1]);
1437
+ if (node.t === 23) deferred.s(deserialized);
1438
+ else deferred.f(deserialized);
1438
1439
  return;
1439
1440
  }
1440
1441
  throw new SerovalMissingInstanceError("Promise");
@@ -1523,8 +1524,8 @@ function deserialize$1(ctx, depth, node) {
1523
1524
  case 21: return deserializeBoxed(ctx, depth, node);
1524
1525
  case 25: return deserializePlugin(ctx, depth, node);
1525
1526
  case 22: return deserializePromiseConstructor(ctx, node);
1526
- case 23: return deserializePromiseResolve(ctx, depth, node);
1527
- case 24: return deserializePromiseReject(ctx, depth, node);
1527
+ case 23:
1528
+ case 24: return deserializePromiseFulfill(ctx, depth, node);
1528
1529
  case 28: return deserializeIteratorFactoryInstance(ctx, depth, node);
1529
1530
  case 30: return deserializeAsyncIteratorFactoryInstance(ctx, depth, node);
1530
1531
  case 31: return deserializeStreamConstructor(ctx, depth, node);
@@ -1917,9 +1918,10 @@ function serializeStringKeyAssignment(ctx, source, mainAssignments, key, value)
1917
1918
  const serialized = serialize$1(ctx, value);
1918
1919
  const check = Number(key);
1919
1920
  const isIdentifier = check >= 0 && check.toString() === key || isValidIdentifier(key);
1920
- if (isIndexedValueInStack(base, value)) if (isIdentifier && check !== check) createObjectAssign(ctx, source.i, key, serialized);
1921
- else createArrayAssign(ctx, source.i, isIdentifier ? key : "\"" + key + "\"", serialized);
1922
- 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 {
1923
1925
  const parentAssignment = base.assignments;
1924
1926
  base.assignments = mainAssignments;
1925
1927
  if (isIdentifier && check !== check) createObjectAssign(ctx, source.i, key, serialized);
@@ -2546,7 +2548,6 @@ function parseObjectPhase2(ctx, depth, id, current, currentClass) {
2546
2548
  case DataView: return parseDataView(ctx, depth, id, current);
2547
2549
  case Map: return parseMap(ctx, depth, id, current);
2548
2550
  case Set: return parseSet(ctx, depth, id, current);
2549
- default: break;
2550
2551
  }
2551
2552
  if (currentClass === Promise || current instanceof Promise) return parsePromise(ctx, depth, id, current);
2552
2553
  const currentFeatures = ctx.base.features;
@@ -2554,7 +2555,6 @@ function parseObjectPhase2(ctx, depth, id, current, currentClass) {
2554
2555
  if (currentFeatures & 16) switch (currentClass) {
2555
2556
  case BigInt64Array:
2556
2557
  case BigUint64Array: return parseBigIntTypedArray(ctx, depth, id, current);
2557
- default: break;
2558
2558
  }
2559
2559
  if (currentFeatures & 1 && typeof AggregateError !== "undefined" && (currentClass === AggregateError || current instanceof AggregateError)) return parseAggregateError(ctx, depth, id, current);
2560
2560
  if (currentFeatures & 64 && typeof Temporal !== "undefined") switch (currentClass) {
@@ -2566,7 +2566,6 @@ function parseObjectPhase2(ctx, depth, id, current, currentClass) {
2566
2566
  case Temporal.PlainTime: return createTemporalNode(id, 5, current);
2567
2567
  case Temporal.PlainYearMonth: return createTemporalNode(id, 6, current);
2568
2568
  case Temporal.ZonedDateTime: return createTemporalNode(id, 7, current);
2569
- default: break;
2570
2569
  }
2571
2570
  if (current instanceof Error) return parseError(ctx, depth, id, current);
2572
2571
  if (SYM_ITERATOR in current || SYM_ASYNC_ITERATOR in current) return parsePlainObject(ctx, depth, id, current, !!currentClass);