@marcuspuchalla/nachos 0.1.3 → 0.2.0

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.
Files changed (68) hide show
  1. package/CHANGELOG.md +75 -0
  2. package/dist/{chunk-PTWN7K3Y.cjs → chunk-3Z45RBZP.cjs} +469 -244
  3. package/dist/chunk-3Z45RBZP.cjs.map +1 -0
  4. package/dist/{chunk-2MTLSQ7E.js → chunk-EDXZTSIA.js} +224 -166
  5. package/dist/chunk-EDXZTSIA.js.map +1 -0
  6. package/dist/{chunk-R62CQQNI.cjs → chunk-HMUA5KLG.cjs} +239 -181
  7. package/dist/chunk-HMUA5KLG.cjs.map +1 -0
  8. package/dist/{chunk-ZDZ2B5PE.js → chunk-JESIF5IF.js} +7 -3
  9. package/dist/chunk-JESIF5IF.js.map +1 -0
  10. package/dist/{chunk-5A5T56JB.js → chunk-LWNWC2O7.js} +442 -217
  11. package/dist/chunk-LWNWC2O7.js.map +1 -0
  12. package/dist/{chunk-PD72MVTX.cjs → chunk-P6A2OOIY.cjs} +7 -3
  13. package/dist/chunk-P6A2OOIY.cjs.map +1 -0
  14. package/dist/encoder/index.cjs +14 -14
  15. package/dist/encoder/index.d.cts +5 -4
  16. package/dist/encoder/index.d.ts +5 -4
  17. package/dist/encoder/index.js +2 -2
  18. package/dist/index.cjs +58 -39
  19. package/dist/index.cjs.map +1 -1
  20. package/dist/index.d.cts +40 -21
  21. package/dist/index.d.ts +40 -21
  22. package/dist/index.js +37 -17
  23. package/dist/index.js.map +1 -1
  24. package/dist/metafile-cjs.json +1 -1
  25. package/dist/metafile-esm.json +1 -1
  26. package/dist/parser/index.cjs +21 -21
  27. package/dist/parser/index.d.cts +4 -2
  28. package/dist/parser/index.d.ts +4 -2
  29. package/dist/parser/index.js +2 -2
  30. package/dist/{types-DvNlfbKB.d.cts → types-eG2qalpr.d.cts} +27 -1
  31. package/dist/{types-DvNlfbKB.d.ts → types-eG2qalpr.d.ts} +27 -1
  32. package/dist/{useCborSimpleEncoder-TVxzNJ_9.d.ts → useCborSimpleEncoder-CamvS-_N.d.ts} +7 -3
  33. package/dist/{useCborSimpleEncoder-ButVU988.d.cts → useCborSimpleEncoder-DXgPx62d.d.cts} +7 -3
  34. package/dist/{useCborTag-xV2Pz2VY.d.ts → useCborTag-D4d7xG3-.d.cts} +9 -4
  35. package/dist/{useCborTag-Cs1CZuXZ.d.cts → useCborTag-TYst1KR6.d.ts} +9 -4
  36. package/package.json +1 -1
  37. package/src/__tests__/audit-fixes.test.ts +141 -0
  38. package/src/__tests__/public-api.test.ts +153 -0
  39. package/src/__tests__/roundtrip.test.ts +5 -6
  40. package/src/encoder/__tests__/cbor-collection-encoder.test.ts +103 -5
  41. package/src/encoder/__tests__/cbor-encoder-errors.test.ts +40 -5
  42. package/src/encoder/__tests__/cbor-simple-encoder.test.ts +126 -0
  43. package/src/encoder/composables/useCborCollectionEncoder.ts +30 -26
  44. package/src/encoder/composables/useCborEncoder.ts +40 -0
  45. package/src/encoder/composables/useCborSimpleEncoder.ts +40 -9
  46. package/src/encoder/types.ts +9 -4
  47. package/src/encoder/utils.ts +33 -1
  48. package/src/index.ts +39 -20
  49. package/src/parser/__tests__/buffer-native-parsing.test.ts +338 -0
  50. package/src/parser/__tests__/cbor-map-duplicate-keys.test.ts +97 -7
  51. package/src/parser/__tests__/cbor-security-dos-protection.test.ts +164 -31
  52. package/src/parser/__tests__/cbor-standard-tags.test.ts +75 -7
  53. package/src/parser/__tests__/cbor-tag-reparse-fix.test.ts +268 -0
  54. package/src/parser/__tests__/utils-errors.test.ts +11 -3
  55. package/src/parser/composables/useCborCollection.ts +51 -45
  56. package/src/parser/composables/useCborDiagnostic.ts +28 -0
  57. package/src/parser/composables/useCborFloat.ts +2 -1
  58. package/src/parser/composables/useCborInteger.ts +24 -10
  59. package/src/parser/composables/useCborParser.ts +448 -208
  60. package/src/parser/composables/useCborTag.ts +53 -38
  61. package/src/parser/types.ts +32 -1
  62. package/src/parser/utils.ts +52 -0
  63. package/dist/chunk-2MTLSQ7E.js.map +0 -1
  64. package/dist/chunk-5A5T56JB.js.map +0 -1
  65. package/dist/chunk-PD72MVTX.cjs.map +0 -1
  66. package/dist/chunk-PTWN7K3Y.cjs.map +0 -1
  67. package/dist/chunk-R62CQQNI.cjs.map +0 -1
  68. package/dist/chunk-ZDZ2B5PE.js.map +0 -1
@@ -1,10 +1,11 @@
1
- import { useCborByteString, useCborTextString, INDEFINITE_SYMBOL, ALL_ENTRIES_SYMBOL } from './chunk-ZDZ2B5PE.js';
1
+ import { useCborByteString, useCborTextString, INDEFINITE_SYMBOL, ALL_ENTRIES_SYMBOL } from './chunk-JESIF5IF.js';
2
2
 
3
3
  // src/encoder/types.ts
4
4
  var DEFAULT_ENCODE_OPTIONS = {
5
5
  canonical: false,
6
6
  allowIndefinite: true,
7
7
  rejectDuplicateKeys: false,
8
+ mapKeyOrder: "length-first",
8
9
  maxDepth: 64,
9
10
  maxOutputSize: 100 * 1024 * 1024
10
11
  // 100 MB
@@ -40,6 +41,20 @@ function compareBytes(a, b) {
40
41
  }
41
42
  return 0;
42
43
  }
44
+ function compareBytesLexicographic(a, b) {
45
+ const min = Math.min(a.length, b.length);
46
+ for (let i = 0; i < min; i++) {
47
+ const byteA = a[i];
48
+ const byteB = b[i];
49
+ if (byteA !== byteB) {
50
+ return byteA - byteB;
51
+ }
52
+ }
53
+ return a.length - b.length;
54
+ }
55
+ function compareMapKeys(a, b, order = "length-first") {
56
+ return order === "bytewise" ? compareBytesLexicographic(a, b) : compareBytes(a, b);
57
+ }
43
58
  function writeUint(value, bytes) {
44
59
  const result = new Uint8Array(bytes);
45
60
  for (let i = bytes - 1; i >= 0; i--) {
@@ -259,11 +274,172 @@ function useCborStringEncoder(globalOptions) {
259
274
  };
260
275
  }
261
276
 
277
+ // src/encoder/composables/useCborSimpleEncoder.ts
278
+ function useCborSimpleEncoder(_globalOptions) {
279
+ const { encodeInteger } = useCborIntegerEncoder();
280
+ const encodeSimple = (value) => {
281
+ let byte;
282
+ if (value === false) {
283
+ byte = 244;
284
+ } else if (value === true) {
285
+ byte = 245;
286
+ } else if (value === null) {
287
+ byte = 246;
288
+ } else if (value === void 0) {
289
+ byte = 247;
290
+ } else {
291
+ throw new Error(`Unsupported simple value: ${value}`);
292
+ }
293
+ return {
294
+ bytes: new Uint8Array([byte]),
295
+ hex: bytesToHex(new Uint8Array([byte]))
296
+ };
297
+ };
298
+ const encodeFloat16Bytes = (value) => {
299
+ if (Object.is(value, -0)) return new Uint8Array([128, 0]);
300
+ if (value === 0) return new Uint8Array([0, 0]);
301
+ if (Number.isNaN(value)) return new Uint8Array([126, 0]);
302
+ if (value === Infinity) return new Uint8Array([124, 0]);
303
+ if (value === -Infinity) return new Uint8Array([252, 0]);
304
+ const sign = value < 0 ? 1 : 0;
305
+ const absValue = Math.abs(value);
306
+ const buffer = new ArrayBuffer(8);
307
+ const view = new DataView(buffer);
308
+ view.setFloat64(0, absValue, false);
309
+ const bits = view.getBigUint64(0, false);
310
+ const exp64 = Number(bits >> 52n & 0x7ffn) - 1023;
311
+ const mant64 = Number(bits & 0xfffffffffffffn);
312
+ const mant64n = BigInt(mant64);
313
+ let exp16;
314
+ let mant16;
315
+ if (exp64 < -24) {
316
+ exp16 = 0;
317
+ mant16 = 0;
318
+ } else if (exp64 < -14) {
319
+ exp16 = 0;
320
+ const shift = -14 - exp64;
321
+ const fullMant = 1n << 10n | mant64n >> 42n;
322
+ const lostFromExtract = mant64n & (1n << 42n) - 1n;
323
+ const shiftN = BigInt(shift);
324
+ const guardBit = Number(fullMant >> shiftN - 1n & 1n);
325
+ const stickyBitsBelow = shiftN > 1n ? fullMant & (1n << shiftN - 1n) - 1n : 0n;
326
+ const sticky = stickyBitsBelow !== 0n || lostFromExtract !== 0n ? 1 : 0;
327
+ const truncated = Number(fullMant >> shiftN);
328
+ const lsb = truncated & 1;
329
+ mant16 = truncated + (guardBit & (sticky | lsb));
330
+ } else if (exp64 > 15) {
331
+ exp16 = 31;
332
+ mant16 = 0;
333
+ } else {
334
+ exp16 = exp64 + 15;
335
+ const truncated = Number(mant64n >> 42n);
336
+ const guardBit = Number(mant64n >> 41n & 1n);
337
+ const stickyBits = (mant64n & (1n << 41n) - 1n) !== 0n ? 1 : 0;
338
+ const lsb = truncated & 1;
339
+ mant16 = truncated + (guardBit & (stickyBits | lsb));
340
+ if (mant16 > 1023) {
341
+ mant16 = 0;
342
+ exp16 += 1;
343
+ }
344
+ }
345
+ const float16 = sign << 15 | exp16 << 10 | mant16;
346
+ return new Uint8Array([
347
+ float16 >> 8 & 255,
348
+ float16 & 255
349
+ ]);
350
+ };
351
+ const encodeFloat32Bytes = (value) => {
352
+ const buffer = new ArrayBuffer(4);
353
+ const view = new DataView(buffer);
354
+ view.setFloat32(0, value, false);
355
+ return new Uint8Array(buffer);
356
+ };
357
+ const encodeFloat64Bytes = (value) => {
358
+ const buffer = new ArrayBuffer(8);
359
+ const view = new DataView(buffer);
360
+ view.setFloat64(0, value, false);
361
+ return new Uint8Array(buffer);
362
+ };
363
+ const canBeFloat16 = (value) => {
364
+ if (!Number.isFinite(value) || Object.is(value, 0) || Object.is(value, -0)) {
365
+ return true;
366
+ }
367
+ const absValue = Math.abs(value);
368
+ if (absValue < 5960464477539063e-23 || absValue > 65504) {
369
+ return false;
370
+ }
371
+ const bytes = encodeFloat16Bytes(value);
372
+ const view = new DataView(bytes.buffer);
373
+ const bits = view.getUint16(0, false);
374
+ const sign = bits >> 15 & 1;
375
+ const exp = bits >> 10 & 31;
376
+ const mant = bits & 1023;
377
+ let decoded;
378
+ if (exp === 0) {
379
+ decoded = (sign ? -1 : 1) * Math.pow(2, -14) * (mant / 1024);
380
+ } else if (exp === 31) {
381
+ decoded = mant === 0 ? sign ? -Infinity : Infinity : NaN;
382
+ } else {
383
+ decoded = (sign ? -1 : 1) * Math.pow(2, exp - 15) * (1 + mant / 1024);
384
+ }
385
+ return decoded === value;
386
+ };
387
+ const canBeFloat32 = (value) => {
388
+ if (!Number.isFinite(value) || Object.is(value, 0) || Object.is(value, -0)) {
389
+ return true;
390
+ }
391
+ const buffer = new ArrayBuffer(4);
392
+ const view = new DataView(buffer);
393
+ view.setFloat32(0, value, false);
394
+ const decoded = view.getFloat32(0, false);
395
+ return decoded === value;
396
+ };
397
+ const isInteger = (value) => {
398
+ return Number.isInteger(value) && Number.isSafeInteger(value);
399
+ };
400
+ const encodeFloat = (value, precision) => {
401
+ let bytes;
402
+ if (isInteger(value) && !precision) {
403
+ return encodeInteger(value);
404
+ }
405
+ if (precision === 16) {
406
+ const floatBytes = encodeFloat16Bytes(value);
407
+ bytes = new Uint8Array([249, ...floatBytes]);
408
+ } else if (precision === 32) {
409
+ const floatBytes = encodeFloat32Bytes(value);
410
+ bytes = new Uint8Array([250, ...floatBytes]);
411
+ } else if (precision === 64) {
412
+ const floatBytes = encodeFloat64Bytes(value);
413
+ bytes = new Uint8Array([251, ...floatBytes]);
414
+ } else {
415
+ if (canBeFloat16(value)) {
416
+ const floatBytes = encodeFloat16Bytes(value);
417
+ bytes = new Uint8Array([249, ...floatBytes]);
418
+ } else if (canBeFloat32(value)) {
419
+ const floatBytes = encodeFloat32Bytes(value);
420
+ bytes = new Uint8Array([250, ...floatBytes]);
421
+ } else {
422
+ const floatBytes = encodeFloat64Bytes(value);
423
+ bytes = new Uint8Array([251, ...floatBytes]);
424
+ }
425
+ }
426
+ return {
427
+ bytes,
428
+ hex: bytesToHex(bytes)
429
+ };
430
+ };
431
+ return {
432
+ encodeSimple,
433
+ encodeFloat
434
+ };
435
+ }
436
+
262
437
  // src/encoder/composables/useCborCollectionEncoder.ts
263
438
  function useCborCollectionEncoder(globalOptions) {
264
439
  const options = { ...DEFAULT_ENCODE_OPTIONS, ...globalOptions };
265
440
  const { encodeInteger } = useCborIntegerEncoder();
266
441
  const { encodeTextString, encodeByteString } = useCborStringEncoder(globalOptions);
442
+ const { encodeFloat } = useCborSimpleEncoder();
267
443
  const { isCborByteString } = useCborByteString();
268
444
  const { isCborTextString } = useCborTextString();
269
445
  let mainEncode = null;
@@ -278,7 +454,15 @@ function useCborCollectionEncoder(globalOptions) {
278
454
  return new Uint8Array([246]);
279
455
  } else if (typeof value === "boolean") {
280
456
  return new Uint8Array([value ? 245 : 244]);
281
- } else if (typeof value === "number" || typeof value === "bigint") {
457
+ } else if (typeof value === "number") {
458
+ if (Object.is(value, -0)) {
459
+ return encodeFloat(value, 16).bytes;
460
+ }
461
+ if (Number.isInteger(value) && Number.isSafeInteger(value)) {
462
+ return encodeInteger(value).bytes;
463
+ }
464
+ return encodeFloat(value).bytes;
465
+ } else if (typeof value === "bigint") {
282
466
  return encodeInteger(value).bytes;
283
467
  } else if (typeof value === "string" || isCborTextString(value)) {
284
468
  return encodeTextString(value).bytes;
@@ -358,10 +542,6 @@ function useCborCollectionEncoder(globalOptions) {
358
542
  parts.push(encoded);
359
543
  }
360
544
  const result = concatenateUint8Arrays(parts);
361
- ctx.bytesWritten += result.length;
362
- if (ctx.bytesWritten > ctx.options.maxOutputSize) {
363
- throw new Error("Encoded output exceeds maximum size");
364
- }
365
545
  return {
366
546
  bytes: result,
367
547
  hex: bytesToHex(result)
@@ -380,7 +560,6 @@ function useCborCollectionEncoder(globalOptions) {
380
560
  }
381
561
  const ctx = {
382
562
  depth: 0,
383
- bytesWritten: 0,
384
563
  options
385
564
  };
386
565
  return encodeArrayInternal(array, ctx);
@@ -395,7 +574,6 @@ function useCborCollectionEncoder(globalOptions) {
395
574
  const parts = [new Uint8Array([159])];
396
575
  const ctx = {
397
576
  depth: 0,
398
- bytesWritten: 0,
399
577
  options
400
578
  };
401
579
  for (const item of array) {
@@ -416,17 +594,22 @@ function useCborCollectionEncoder(globalOptions) {
416
594
  } else {
417
595
  entries = map instanceof Map ? Array.from(map.entries()) : Object.entries(map);
418
596
  }
597
+ let preEncodedKeys = null;
419
598
  if (ctx.options.canonical && !map[ALL_ENTRIES_SYMBOL]) {
420
- entries.sort((a, b) => {
421
- const keyA = encodeValue(a[0], { ...ctx, depth: ctx.depth + 1 });
422
- const keyB = encodeValue(b[0], { ...ctx, depth: ctx.depth + 1 });
423
- return compareBytes(keyA, keyB);
424
- });
599
+ const childCtx = { ...ctx, depth: ctx.depth + 1 };
600
+ const withEncodedKeys = entries.map((entry) => ({
601
+ encodedKey: encodeValue(entry[0], childCtx),
602
+ entry
603
+ }));
604
+ const keyOrder = ctx.options.mapKeyOrder ?? "length-first";
605
+ withEncodedKeys.sort((a, b) => compareMapKeys(a.encodedKey, b.encodedKey, keyOrder));
606
+ entries = withEncodedKeys.map((t) => t.entry);
607
+ preEncodedKeys = withEncodedKeys.map((t) => t.encodedKey);
425
608
  }
426
609
  if (ctx.options.rejectDuplicateKeys) {
427
610
  const seen = /* @__PURE__ */ new Set();
428
- for (const [key] of entries) {
429
- const keyBytes = encodeValue(key, { ...ctx, depth: ctx.depth + 1, bytesWritten: 0 });
611
+ const keysForDupCheck = preEncodedKeys ?? entries.map((e) => encodeValue(e[0], { ...ctx, depth: ctx.depth + 1 }));
612
+ for (const keyBytes of keysForDupCheck) {
430
613
  const keyHex = bytesToHex(keyBytes);
431
614
  if (seen.has(keyHex)) {
432
615
  throw new Error("Duplicate map key detected");
@@ -443,10 +626,6 @@ function useCborCollectionEncoder(globalOptions) {
443
626
  parts.push(encodedValue);
444
627
  }
445
628
  const result = concatenateUint8Arrays(parts);
446
- ctx.bytesWritten += result.length;
447
- if (ctx.bytesWritten > ctx.options.maxOutputSize) {
448
- throw new Error("Encoded output exceeds maximum size");
449
- }
450
629
  return {
451
630
  bytes: result,
452
631
  hex: bytesToHex(result)
@@ -465,7 +644,6 @@ function useCborCollectionEncoder(globalOptions) {
465
644
  }
466
645
  const ctx = {
467
646
  depth: 0,
468
- bytesWritten: 0,
469
647
  options
470
648
  };
471
649
  return encodeMapInternal(map, ctx);
@@ -481,7 +659,6 @@ function useCborCollectionEncoder(globalOptions) {
481
659
  const parts = [new Uint8Array([191])];
482
660
  const ctx = {
483
661
  depth: 0,
484
- bytesWritten: 0,
485
662
  options
486
663
  };
487
664
  for (const [key, value] of entries) {
@@ -506,149 +683,6 @@ function useCborCollectionEncoder(globalOptions) {
506
683
  };
507
684
  }
508
685
 
509
- // src/encoder/composables/useCborSimpleEncoder.ts
510
- function useCborSimpleEncoder(_globalOptions) {
511
- const { encodeInteger } = useCborIntegerEncoder();
512
- const encodeSimple = (value) => {
513
- let byte;
514
- if (value === false) {
515
- byte = 244;
516
- } else if (value === true) {
517
- byte = 245;
518
- } else if (value === null) {
519
- byte = 246;
520
- } else if (value === void 0) {
521
- byte = 247;
522
- } else {
523
- throw new Error(`Unsupported simple value: ${value}`);
524
- }
525
- return {
526
- bytes: new Uint8Array([byte]),
527
- hex: bytesToHex(new Uint8Array([byte]))
528
- };
529
- };
530
- const encodeFloat16Bytes = (value) => {
531
- if (value === 0) return new Uint8Array([0, 0]);
532
- if (value === -0) return new Uint8Array([128, 0]);
533
- if (Number.isNaN(value)) return new Uint8Array([126, 0]);
534
- if (value === Infinity) return new Uint8Array([124, 0]);
535
- if (value === -Infinity) return new Uint8Array([252, 0]);
536
- const sign = value < 0 ? 1 : 0;
537
- const absValue = Math.abs(value);
538
- const buffer = new ArrayBuffer(8);
539
- const view = new DataView(buffer);
540
- view.setFloat64(0, absValue, false);
541
- const bits = view.getBigUint64(0, false);
542
- const exp64 = Number(bits >> 52n & 0x7ffn) - 1023;
543
- const mant64 = Number(bits & 0xfffffffffffffn);
544
- let exp16;
545
- let mant16;
546
- if (exp64 < -24) {
547
- exp16 = 0;
548
- mant16 = 0;
549
- } else if (exp64 < -14) {
550
- exp16 = 0;
551
- const shift = -14 - exp64;
552
- mant16 = (1 << 10 | mant64 >> 42) + ((1 << shift - 1) - 1) >> shift;
553
- } else if (exp64 > 15) {
554
- exp16 = 31;
555
- mant16 = 0;
556
- } else {
557
- exp16 = exp64 + 15;
558
- mant16 = mant64 >> 42;
559
- }
560
- const float16 = sign << 15 | exp16 << 10 | mant16;
561
- return new Uint8Array([
562
- float16 >> 8 & 255,
563
- float16 & 255
564
- ]);
565
- };
566
- const encodeFloat32Bytes = (value) => {
567
- const buffer = new ArrayBuffer(4);
568
- const view = new DataView(buffer);
569
- view.setFloat32(0, value, false);
570
- return new Uint8Array(buffer);
571
- };
572
- const encodeFloat64Bytes = (value) => {
573
- const buffer = new ArrayBuffer(8);
574
- const view = new DataView(buffer);
575
- view.setFloat64(0, value, false);
576
- return new Uint8Array(buffer);
577
- };
578
- const canBeFloat16 = (value) => {
579
- if (!Number.isFinite(value) || value === 0 || value === -0) {
580
- return true;
581
- }
582
- const absValue = Math.abs(value);
583
- if (absValue < 6103515625e-14 || absValue > 65504) {
584
- return false;
585
- }
586
- const bytes = encodeFloat16Bytes(value);
587
- const view = new DataView(bytes.buffer);
588
- const bits = view.getUint16(0, false);
589
- const sign = bits >> 15 & 1;
590
- const exp = bits >> 10 & 31;
591
- const mant = bits & 1023;
592
- let decoded;
593
- if (exp === 0) {
594
- decoded = (sign ? -1 : 1) * Math.pow(2, -14) * (mant / 1024);
595
- } else if (exp === 31) {
596
- decoded = mant === 0 ? sign ? -Infinity : Infinity : NaN;
597
- } else {
598
- decoded = (sign ? -1 : 1) * Math.pow(2, exp - 15) * (1 + mant / 1024);
599
- }
600
- return decoded === value;
601
- };
602
- const canBeFloat32 = (value) => {
603
- if (!Number.isFinite(value) || value === 0 || value === -0) {
604
- return true;
605
- }
606
- const buffer = new ArrayBuffer(4);
607
- const view = new DataView(buffer);
608
- view.setFloat32(0, value, false);
609
- const decoded = view.getFloat32(0, false);
610
- return decoded === value;
611
- };
612
- const isInteger = (value) => {
613
- return Number.isInteger(value) && Number.isSafeInteger(value);
614
- };
615
- const encodeFloat = (value, precision) => {
616
- let bytes;
617
- if (isInteger(value) && !precision) {
618
- return encodeInteger(value);
619
- }
620
- if (precision === 16) {
621
- const floatBytes = encodeFloat16Bytes(value);
622
- bytes = new Uint8Array([249, ...floatBytes]);
623
- } else if (precision === 32) {
624
- const floatBytes = encodeFloat32Bytes(value);
625
- bytes = new Uint8Array([250, ...floatBytes]);
626
- } else if (precision === 64) {
627
- const floatBytes = encodeFloat64Bytes(value);
628
- bytes = new Uint8Array([251, ...floatBytes]);
629
- } else {
630
- if (canBeFloat16(value)) {
631
- const floatBytes = encodeFloat16Bytes(value);
632
- bytes = new Uint8Array([249, ...floatBytes]);
633
- } else if (canBeFloat32(value)) {
634
- const floatBytes = encodeFloat32Bytes(value);
635
- bytes = new Uint8Array([250, ...floatBytes]);
636
- } else {
637
- const floatBytes = encodeFloat64Bytes(value);
638
- bytes = new Uint8Array([251, ...floatBytes]);
639
- }
640
- }
641
- return {
642
- bytes,
643
- hex: bytesToHex(bytes)
644
- };
645
- };
646
- return {
647
- encodeSimple,
648
- encodeFloat
649
- };
650
- }
651
-
652
686
  // src/encoder/composables/useCborTagEncoder.ts
653
687
  function useCborTagEncoder() {
654
688
  const encodeTagNumber = (tagNumber) => {
@@ -713,10 +747,34 @@ function useCborEncoder(globalOptions) {
713
747
  const { isCborByteString } = useCborByteString();
714
748
  const { isCborTextString } = useCborTextString();
715
749
  const encode = (value) => {
750
+ const result = encodeValue(value);
751
+ if (options.maxOutputSize && result.bytes.length > options.maxOutputSize) {
752
+ throw new Error(
753
+ `Encoded output size ${result.bytes.length} bytes exceeds limit of ${options.maxOutputSize} bytes`
754
+ );
755
+ }
756
+ return result;
757
+ };
758
+ let currentDepth = 0;
759
+ const encodeValue = (value) => {
760
+ if (currentDepth > options.maxDepth) {
761
+ throw new Error(`Maximum nesting depth ${options.maxDepth} exceeded`);
762
+ }
763
+ currentDepth++;
764
+ try {
765
+ return encodeValueInner(value);
766
+ } finally {
767
+ currentDepth--;
768
+ }
769
+ };
770
+ const encodeValueInner = (value) => {
716
771
  if (value === null || value === void 0 || typeof value === "boolean") {
717
772
  return encodeSimple(value);
718
773
  }
719
774
  if (typeof value === "number") {
775
+ if (Object.is(value, -0)) {
776
+ return encodeFloat(value, 16);
777
+ }
720
778
  if (Number.isSafeInteger(value)) {
721
779
  return encodeInteger(value);
722
780
  }
@@ -786,5 +844,5 @@ function useCborEncoder(globalOptions) {
786
844
  }
787
845
 
788
846
  export { DEFAULT_ENCODE_OPTIONS, bytesToHex, compareBytes, concatenateUint8Arrays, useCborCollectionEncoder, useCborEncoder, useCborIntegerEncoder, useCborSimpleEncoder, useCborStringEncoder, useCborTagEncoder, writeBigUint, writeUint };
789
- //# sourceMappingURL=chunk-2MTLSQ7E.js.map
790
- //# sourceMappingURL=chunk-2MTLSQ7E.js.map
847
+ //# sourceMappingURL=chunk-EDXZTSIA.js.map
848
+ //# sourceMappingURL=chunk-EDXZTSIA.js.map