@marcuspuchalla/nachos 0.1.1 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +55 -0
- package/dist/{chunk-ZRPJUEIZ.js → chunk-5IWW5H47.js} +546 -227
- package/dist/chunk-5IWW5H47.js.map +1 -0
- package/dist/{chunk-2HBCILJS.cjs → chunk-RVG2BY32.cjs} +545 -226
- package/dist/chunk-RVG2BY32.cjs.map +1 -0
- package/dist/{chunk-2FUTHZQQ.cjs → chunk-S4RXO6IB.cjs} +244 -166
- package/dist/chunk-S4RXO6IB.cjs.map +1 -0
- package/dist/{chunk-7CFYWHS6.js → chunk-UMAX5MX5.js} +244 -166
- package/dist/chunk-UMAX5MX5.js.map +1 -0
- package/dist/encoder/index.cjs +13 -13
- package/dist/encoder/index.d.cts +2 -2
- package/dist/encoder/index.d.ts +2 -2
- package/dist/encoder/index.js +1 -1
- package/dist/index.cjs +32 -32
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +28 -19
- package/dist/index.d.ts +28 -19
- package/dist/index.js +16 -16
- package/dist/index.js.map +1 -1
- package/dist/metafile-cjs.json +1 -1
- package/dist/metafile-esm.json +1 -1
- package/dist/parser/index.cjs +14 -14
- package/dist/parser/index.d.cts +3 -1
- package/dist/parser/index.d.ts +3 -1
- package/dist/parser/index.js +1 -1
- package/dist/{useCborSimpleEncoder-TVxzNJ_9.d.ts → useCborSimpleEncoder-BoKEmjP9.d.ts} +0 -2
- package/dist/{useCborSimpleEncoder-ButVU988.d.cts → useCborSimpleEncoder-C_OHxoB8.d.cts} +0 -2
- package/dist/{useCborTag-B_iaShG6.d.ts → useCborTag-BD6Sqp7p.d.ts} +11 -6
- package/dist/{useCborTag-BfTIV8HM.d.cts → useCborTag-QpZR-Er2.d.cts} +11 -6
- package/package.json +1 -1
- package/src/__tests__/public-api.test.ts +153 -0
- package/src/__tests__/roundtrip.test.ts +701 -0
- package/src/encoder/__tests__/cbor-collection-encoder.test.ts +129 -5
- package/src/encoder/__tests__/cbor-encoder-errors.test.ts +847 -0
- package/src/encoder/__tests__/cbor-simple-encoder.test.ts +126 -0
- package/src/encoder/__tests__/cbor-string-encoder.test.ts +14 -0
- package/src/encoder/composables/useCborCollectionEncoder.ts +56 -23
- package/src/encoder/composables/useCborEncoder.ts +27 -1
- package/src/encoder/composables/useCborSimpleEncoder.ts +40 -8
- package/src/encoder/composables/useCborStringEncoder.ts +23 -10
- package/src/encoder/types.ts +0 -2
- package/src/index.ts +29 -20
- package/src/parser/__tests__/buffer-native-parsing.test.ts +338 -0
- package/src/parser/__tests__/cbor-float-errors.test.ts +41 -0
- package/src/parser/__tests__/cbor-map-duplicate-keys.test.ts +97 -7
- package/src/parser/__tests__/cbor-security-dos-protection.test.ts +166 -33
- package/src/parser/__tests__/cbor-standard-tags.test.ts +104 -7
- package/src/parser/__tests__/cbor-string-errors.test.ts +4 -4
- package/src/parser/__tests__/cbor-tag-errors.test.ts +1 -1
- package/src/parser/__tests__/cbor-tag-reparse-fix.test.ts +268 -0
- package/src/parser/composables/useCborCollection.ts +45 -42
- package/src/parser/composables/useCborFloat.ts +95 -9
- package/src/parser/composables/useCborInteger.ts +24 -10
- package/src/parser/composables/useCborParser.ts +387 -216
- package/src/parser/composables/useCborString.ts +22 -4
- package/src/parser/composables/useCborTag.ts +149 -53
- package/src/parser/utils.ts +11 -0
- package/dist/chunk-2FUTHZQQ.cjs.map +0 -1
- package/dist/chunk-2HBCILJS.cjs.map +0 -1
- package/dist/chunk-7CFYWHS6.js.map +0 -1
- package/dist/chunk-ZRPJUEIZ.js.map +0 -1
- package/src/encoder/composables/#useCborTagEncoder.ts# +0 -158
|
@@ -160,6 +160,9 @@ function useCborStringEncoder(globalOptions) {
|
|
|
160
160
|
const encodeByteString = (data, encodeOptions) => {
|
|
161
161
|
const isIndefinite = isCborByteString(data) && data[chunkPD72MVTX_cjs.INDEFINITE_SYMBOL] === true;
|
|
162
162
|
if (encodeOptions?.indefinite || Array.isArray(data) || isIndefinite) {
|
|
163
|
+
if (options.allowIndefinite === false) {
|
|
164
|
+
throw new Error("Indefinite-length encoding is not allowed");
|
|
165
|
+
}
|
|
163
166
|
if (options.canonical) {
|
|
164
167
|
throw new Error("Indefinite-length encoding not allowed in canonical mode");
|
|
165
168
|
}
|
|
@@ -170,17 +173,20 @@ function useCborStringEncoder(globalOptions) {
|
|
|
170
173
|
return encodeByteStringIndefinite(Array.isArray(bytes2) ? bytes2 : [bytes2]);
|
|
171
174
|
}
|
|
172
175
|
const bytes = isCborByteString(data) ? data.bytes : data;
|
|
176
|
+
if (bytes.length + 9 > options.maxOutputSize) {
|
|
177
|
+
throw new Error(`Encoded output exceeds maximum size`);
|
|
178
|
+
}
|
|
173
179
|
const header = encodeLengthHeader(2, bytes.length);
|
|
174
180
|
const result = concatenateUint8Arrays([header, bytes]);
|
|
175
|
-
if (result.length > options.maxOutputSize) {
|
|
176
|
-
throw new Error("Encoded output exceeds maximum size");
|
|
177
|
-
}
|
|
178
181
|
return {
|
|
179
182
|
bytes: result,
|
|
180
183
|
hex: bytesToHex(result)
|
|
181
184
|
};
|
|
182
185
|
};
|
|
183
186
|
const encodeByteStringIndefinite = (chunks) => {
|
|
187
|
+
if (options.allowIndefinite === false) {
|
|
188
|
+
throw new Error("Indefinite-length encoding is not allowed");
|
|
189
|
+
}
|
|
184
190
|
if (options.canonical) {
|
|
185
191
|
throw new Error("Indefinite-length encoding not allowed in canonical mode");
|
|
186
192
|
}
|
|
@@ -200,6 +206,9 @@ function useCborStringEncoder(globalOptions) {
|
|
|
200
206
|
const encodeTextString = (text, encodeOptions) => {
|
|
201
207
|
const isIndefinite = isCborTextString(text) && text[chunkPD72MVTX_cjs.INDEFINITE_SYMBOL] === true;
|
|
202
208
|
if (encodeOptions?.indefinite || isIndefinite) {
|
|
209
|
+
if (options.allowIndefinite === false) {
|
|
210
|
+
throw new Error("Indefinite-length encoding is not allowed");
|
|
211
|
+
}
|
|
203
212
|
if (options.canonical) {
|
|
204
213
|
throw new Error("Indefinite-length encoding not allowed in canonical mode");
|
|
205
214
|
}
|
|
@@ -212,17 +221,20 @@ function useCborStringEncoder(globalOptions) {
|
|
|
212
221
|
const textStr = isCborTextString(text) ? text.text : text;
|
|
213
222
|
const encoder = new TextEncoder();
|
|
214
223
|
const utf8Bytes = encoder.encode(textStr);
|
|
224
|
+
if (utf8Bytes.length + 9 > options.maxOutputSize) {
|
|
225
|
+
throw new Error(`Encoded output exceeds maximum size`);
|
|
226
|
+
}
|
|
215
227
|
const header = encodeLengthHeader(3, utf8Bytes.length);
|
|
216
228
|
const result = concatenateUint8Arrays([header, utf8Bytes]);
|
|
217
|
-
if (result.length > options.maxOutputSize) {
|
|
218
|
-
throw new Error("Encoded output exceeds maximum size");
|
|
219
|
-
}
|
|
220
229
|
return {
|
|
221
230
|
bytes: result,
|
|
222
231
|
hex: bytesToHex(result)
|
|
223
232
|
};
|
|
224
233
|
};
|
|
225
234
|
const encodeTextStringIndefinite = (chunks) => {
|
|
235
|
+
if (options.allowIndefinite === false) {
|
|
236
|
+
throw new Error("Indefinite-length encoding is not allowed");
|
|
237
|
+
}
|
|
226
238
|
if (options.canonical) {
|
|
227
239
|
throw new Error("Indefinite-length encoding not allowed in canonical mode");
|
|
228
240
|
}
|
|
@@ -249,11 +261,172 @@ function useCborStringEncoder(globalOptions) {
|
|
|
249
261
|
};
|
|
250
262
|
}
|
|
251
263
|
|
|
264
|
+
// src/encoder/composables/useCborSimpleEncoder.ts
|
|
265
|
+
function useCborSimpleEncoder(_globalOptions) {
|
|
266
|
+
const { encodeInteger } = useCborIntegerEncoder();
|
|
267
|
+
const encodeSimple = (value) => {
|
|
268
|
+
let byte;
|
|
269
|
+
if (value === false) {
|
|
270
|
+
byte = 244;
|
|
271
|
+
} else if (value === true) {
|
|
272
|
+
byte = 245;
|
|
273
|
+
} else if (value === null) {
|
|
274
|
+
byte = 246;
|
|
275
|
+
} else if (value === void 0) {
|
|
276
|
+
byte = 247;
|
|
277
|
+
} else {
|
|
278
|
+
throw new Error(`Unsupported simple value: ${value}`);
|
|
279
|
+
}
|
|
280
|
+
return {
|
|
281
|
+
bytes: new Uint8Array([byte]),
|
|
282
|
+
hex: bytesToHex(new Uint8Array([byte]))
|
|
283
|
+
};
|
|
284
|
+
};
|
|
285
|
+
const encodeFloat16Bytes = (value) => {
|
|
286
|
+
if (Object.is(value, -0)) return new Uint8Array([128, 0]);
|
|
287
|
+
if (value === 0) return new Uint8Array([0, 0]);
|
|
288
|
+
if (Number.isNaN(value)) return new Uint8Array([126, 0]);
|
|
289
|
+
if (value === Infinity) return new Uint8Array([124, 0]);
|
|
290
|
+
if (value === -Infinity) return new Uint8Array([252, 0]);
|
|
291
|
+
const sign = value < 0 ? 1 : 0;
|
|
292
|
+
const absValue = Math.abs(value);
|
|
293
|
+
const buffer = new ArrayBuffer(8);
|
|
294
|
+
const view = new DataView(buffer);
|
|
295
|
+
view.setFloat64(0, absValue, false);
|
|
296
|
+
const bits = view.getBigUint64(0, false);
|
|
297
|
+
const exp64 = Number(bits >> 52n & 0x7ffn) - 1023;
|
|
298
|
+
const mant64 = Number(bits & 0xfffffffffffffn);
|
|
299
|
+
const mant64n = BigInt(mant64);
|
|
300
|
+
let exp16;
|
|
301
|
+
let mant16;
|
|
302
|
+
if (exp64 < -24) {
|
|
303
|
+
exp16 = 0;
|
|
304
|
+
mant16 = 0;
|
|
305
|
+
} else if (exp64 < -14) {
|
|
306
|
+
exp16 = 0;
|
|
307
|
+
const shift = -14 - exp64;
|
|
308
|
+
const fullMant = 1n << 10n | mant64n >> 42n;
|
|
309
|
+
const lostFromExtract = mant64n & (1n << 42n) - 1n;
|
|
310
|
+
const shiftN = BigInt(shift);
|
|
311
|
+
const guardBit = Number(fullMant >> shiftN - 1n & 1n);
|
|
312
|
+
const stickyBitsBelow = shiftN > 1n ? fullMant & (1n << shiftN - 1n) - 1n : 0n;
|
|
313
|
+
const sticky = stickyBitsBelow !== 0n || lostFromExtract !== 0n ? 1 : 0;
|
|
314
|
+
const truncated = Number(fullMant >> shiftN);
|
|
315
|
+
const lsb = truncated & 1;
|
|
316
|
+
mant16 = truncated + (guardBit & (sticky | lsb));
|
|
317
|
+
} else if (exp64 > 15) {
|
|
318
|
+
exp16 = 31;
|
|
319
|
+
mant16 = 0;
|
|
320
|
+
} else {
|
|
321
|
+
exp16 = exp64 + 15;
|
|
322
|
+
const truncated = Number(mant64n >> 42n);
|
|
323
|
+
const guardBit = Number(mant64n >> 41n & 1n);
|
|
324
|
+
const stickyBits = (mant64n & (1n << 41n) - 1n) !== 0n ? 1 : 0;
|
|
325
|
+
const lsb = truncated & 1;
|
|
326
|
+
mant16 = truncated + (guardBit & (stickyBits | lsb));
|
|
327
|
+
if (mant16 > 1023) {
|
|
328
|
+
mant16 = 0;
|
|
329
|
+
exp16 += 1;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
const float16 = sign << 15 | exp16 << 10 | mant16;
|
|
333
|
+
return new Uint8Array([
|
|
334
|
+
float16 >> 8 & 255,
|
|
335
|
+
float16 & 255
|
|
336
|
+
]);
|
|
337
|
+
};
|
|
338
|
+
const encodeFloat32Bytes = (value) => {
|
|
339
|
+
const buffer = new ArrayBuffer(4);
|
|
340
|
+
const view = new DataView(buffer);
|
|
341
|
+
view.setFloat32(0, value, false);
|
|
342
|
+
return new Uint8Array(buffer);
|
|
343
|
+
};
|
|
344
|
+
const encodeFloat64Bytes = (value) => {
|
|
345
|
+
const buffer = new ArrayBuffer(8);
|
|
346
|
+
const view = new DataView(buffer);
|
|
347
|
+
view.setFloat64(0, value, false);
|
|
348
|
+
return new Uint8Array(buffer);
|
|
349
|
+
};
|
|
350
|
+
const canBeFloat16 = (value) => {
|
|
351
|
+
if (!Number.isFinite(value) || Object.is(value, 0) || Object.is(value, -0)) {
|
|
352
|
+
return true;
|
|
353
|
+
}
|
|
354
|
+
const absValue = Math.abs(value);
|
|
355
|
+
if (absValue < 6103515625e-14 || absValue > 65504) {
|
|
356
|
+
return false;
|
|
357
|
+
}
|
|
358
|
+
const bytes = encodeFloat16Bytes(value);
|
|
359
|
+
const view = new DataView(bytes.buffer);
|
|
360
|
+
const bits = view.getUint16(0, false);
|
|
361
|
+
const sign = bits >> 15 & 1;
|
|
362
|
+
const exp = bits >> 10 & 31;
|
|
363
|
+
const mant = bits & 1023;
|
|
364
|
+
let decoded;
|
|
365
|
+
if (exp === 0) {
|
|
366
|
+
decoded = (sign ? -1 : 1) * Math.pow(2, -14) * (mant / 1024);
|
|
367
|
+
} else if (exp === 31) {
|
|
368
|
+
decoded = mant === 0 ? sign ? -Infinity : Infinity : NaN;
|
|
369
|
+
} else {
|
|
370
|
+
decoded = (sign ? -1 : 1) * Math.pow(2, exp - 15) * (1 + mant / 1024);
|
|
371
|
+
}
|
|
372
|
+
return decoded === value;
|
|
373
|
+
};
|
|
374
|
+
const canBeFloat32 = (value) => {
|
|
375
|
+
if (!Number.isFinite(value) || Object.is(value, 0) || Object.is(value, -0)) {
|
|
376
|
+
return true;
|
|
377
|
+
}
|
|
378
|
+
const buffer = new ArrayBuffer(4);
|
|
379
|
+
const view = new DataView(buffer);
|
|
380
|
+
view.setFloat32(0, value, false);
|
|
381
|
+
const decoded = view.getFloat32(0, false);
|
|
382
|
+
return decoded === value;
|
|
383
|
+
};
|
|
384
|
+
const isInteger = (value) => {
|
|
385
|
+
return Number.isInteger(value) && Number.isSafeInteger(value);
|
|
386
|
+
};
|
|
387
|
+
const encodeFloat = (value, precision) => {
|
|
388
|
+
let bytes;
|
|
389
|
+
if (isInteger(value) && !precision) {
|
|
390
|
+
return encodeInteger(value);
|
|
391
|
+
}
|
|
392
|
+
if (precision === 16) {
|
|
393
|
+
const floatBytes = encodeFloat16Bytes(value);
|
|
394
|
+
bytes = new Uint8Array([249, ...floatBytes]);
|
|
395
|
+
} else if (precision === 32) {
|
|
396
|
+
const floatBytes = encodeFloat32Bytes(value);
|
|
397
|
+
bytes = new Uint8Array([250, ...floatBytes]);
|
|
398
|
+
} else if (precision === 64) {
|
|
399
|
+
const floatBytes = encodeFloat64Bytes(value);
|
|
400
|
+
bytes = new Uint8Array([251, ...floatBytes]);
|
|
401
|
+
} else {
|
|
402
|
+
if (canBeFloat16(value)) {
|
|
403
|
+
const floatBytes = encodeFloat16Bytes(value);
|
|
404
|
+
bytes = new Uint8Array([249, ...floatBytes]);
|
|
405
|
+
} else if (canBeFloat32(value)) {
|
|
406
|
+
const floatBytes = encodeFloat32Bytes(value);
|
|
407
|
+
bytes = new Uint8Array([250, ...floatBytes]);
|
|
408
|
+
} else {
|
|
409
|
+
const floatBytes = encodeFloat64Bytes(value);
|
|
410
|
+
bytes = new Uint8Array([251, ...floatBytes]);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
return {
|
|
414
|
+
bytes,
|
|
415
|
+
hex: bytesToHex(bytes)
|
|
416
|
+
};
|
|
417
|
+
};
|
|
418
|
+
return {
|
|
419
|
+
encodeSimple,
|
|
420
|
+
encodeFloat
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
|
|
252
424
|
// src/encoder/composables/useCborCollectionEncoder.ts
|
|
253
425
|
function useCborCollectionEncoder(globalOptions) {
|
|
254
426
|
const options = { ...DEFAULT_ENCODE_OPTIONS, ...globalOptions };
|
|
255
427
|
const { encodeInteger } = useCborIntegerEncoder();
|
|
256
428
|
const { encodeTextString, encodeByteString } = useCborStringEncoder(globalOptions);
|
|
429
|
+
const { encodeFloat } = useCborSimpleEncoder();
|
|
257
430
|
const { isCborByteString } = chunkPD72MVTX_cjs.useCborByteString();
|
|
258
431
|
const { isCborTextString } = chunkPD72MVTX_cjs.useCborTextString();
|
|
259
432
|
let mainEncode = null;
|
|
@@ -268,7 +441,15 @@ function useCborCollectionEncoder(globalOptions) {
|
|
|
268
441
|
return new Uint8Array([246]);
|
|
269
442
|
} else if (typeof value === "boolean") {
|
|
270
443
|
return new Uint8Array([value ? 245 : 244]);
|
|
271
|
-
} else if (typeof value === "number"
|
|
444
|
+
} else if (typeof value === "number") {
|
|
445
|
+
if (Object.is(value, -0)) {
|
|
446
|
+
return encodeFloat(value, 16).bytes;
|
|
447
|
+
}
|
|
448
|
+
if (Number.isInteger(value) && Number.isSafeInteger(value)) {
|
|
449
|
+
return encodeInteger(value).bytes;
|
|
450
|
+
}
|
|
451
|
+
return encodeFloat(value).bytes;
|
|
452
|
+
} else if (typeof value === "bigint") {
|
|
272
453
|
return encodeInteger(value).bytes;
|
|
273
454
|
} else if (typeof value === "string" || isCborTextString(value)) {
|
|
274
455
|
return encodeTextString(value).bytes;
|
|
@@ -278,6 +459,9 @@ function useCborCollectionEncoder(globalOptions) {
|
|
|
278
459
|
const isIndefinite = value[chunkPD72MVTX_cjs.INDEFINITE_SYMBOL] === true;
|
|
279
460
|
const newCtx = { ...ctx, depth: ctx.depth + 1 };
|
|
280
461
|
if (isIndefinite) {
|
|
462
|
+
if (ctx.options.allowIndefinite === false) {
|
|
463
|
+
throw new Error("Indefinite-length encoding is not allowed");
|
|
464
|
+
}
|
|
281
465
|
const parts = [new Uint8Array([159])];
|
|
282
466
|
for (const item of value) {
|
|
283
467
|
const encoded = encodeValue(item, newCtx);
|
|
@@ -297,6 +481,9 @@ function useCborCollectionEncoder(globalOptions) {
|
|
|
297
481
|
const isIndefinite = value[chunkPD72MVTX_cjs.INDEFINITE_SYMBOL] === true;
|
|
298
482
|
const newCtx = { ...ctx, depth: ctx.depth + 1 };
|
|
299
483
|
if (isIndefinite) {
|
|
484
|
+
if (ctx.options.allowIndefinite === false) {
|
|
485
|
+
throw new Error("Indefinite-length encoding is not allowed");
|
|
486
|
+
}
|
|
300
487
|
const entries = value instanceof Map ? Array.from(value.entries()) : Object.entries(value);
|
|
301
488
|
const parts = [new Uint8Array([191])];
|
|
302
489
|
for (const [key, val] of entries) {
|
|
@@ -342,10 +529,6 @@ function useCborCollectionEncoder(globalOptions) {
|
|
|
342
529
|
parts.push(encoded);
|
|
343
530
|
}
|
|
344
531
|
const result = concatenateUint8Arrays(parts);
|
|
345
|
-
ctx.bytesWritten += result.length;
|
|
346
|
-
if (ctx.bytesWritten > ctx.options.maxOutputSize) {
|
|
347
|
-
throw new Error("Encoded output exceeds maximum size");
|
|
348
|
-
}
|
|
349
532
|
return {
|
|
350
533
|
bytes: result,
|
|
351
534
|
hex: bytesToHex(result)
|
|
@@ -354,6 +537,9 @@ function useCborCollectionEncoder(globalOptions) {
|
|
|
354
537
|
const encodeArray = (array, encodeOptions) => {
|
|
355
538
|
const isIndefinite = array[chunkPD72MVTX_cjs.INDEFINITE_SYMBOL] === true;
|
|
356
539
|
if (encodeOptions?.indefinite || isIndefinite) {
|
|
540
|
+
if (options.allowIndefinite === false) {
|
|
541
|
+
throw new Error("Indefinite-length encoding is not allowed");
|
|
542
|
+
}
|
|
357
543
|
if (options.canonical) {
|
|
358
544
|
throw new Error("Indefinite-length encoding not allowed in canonical mode");
|
|
359
545
|
}
|
|
@@ -361,19 +547,20 @@ function useCborCollectionEncoder(globalOptions) {
|
|
|
361
547
|
}
|
|
362
548
|
const ctx = {
|
|
363
549
|
depth: 0,
|
|
364
|
-
bytesWritten: 0,
|
|
365
550
|
options
|
|
366
551
|
};
|
|
367
552
|
return encodeArrayInternal(array, ctx);
|
|
368
553
|
};
|
|
369
554
|
const encodeArrayIndefinite = (array) => {
|
|
555
|
+
if (options.allowIndefinite === false) {
|
|
556
|
+
throw new Error("Indefinite-length encoding is not allowed");
|
|
557
|
+
}
|
|
370
558
|
if (options.canonical) {
|
|
371
559
|
throw new Error("Indefinite-length encoding not allowed in canonical mode");
|
|
372
560
|
}
|
|
373
561
|
const parts = [new Uint8Array([159])];
|
|
374
562
|
const ctx = {
|
|
375
563
|
depth: 0,
|
|
376
|
-
bytesWritten: 0,
|
|
377
564
|
options
|
|
378
565
|
};
|
|
379
566
|
for (const item of array) {
|
|
@@ -394,12 +581,27 @@ function useCborCollectionEncoder(globalOptions) {
|
|
|
394
581
|
} else {
|
|
395
582
|
entries = map instanceof Map ? Array.from(map.entries()) : Object.entries(map);
|
|
396
583
|
}
|
|
584
|
+
let preEncodedKeys = null;
|
|
397
585
|
if (ctx.options.canonical && !map[chunkPD72MVTX_cjs.ALL_ENTRIES_SYMBOL]) {
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
});
|
|
586
|
+
const childCtx = { ...ctx, depth: ctx.depth + 1 };
|
|
587
|
+
const withEncodedKeys = entries.map((entry) => ({
|
|
588
|
+
encodedKey: encodeValue(entry[0], childCtx),
|
|
589
|
+
entry
|
|
590
|
+
}));
|
|
591
|
+
withEncodedKeys.sort((a, b) => compareBytes(a.encodedKey, b.encodedKey));
|
|
592
|
+
entries = withEncodedKeys.map((t) => t.entry);
|
|
593
|
+
preEncodedKeys = withEncodedKeys.map((t) => t.encodedKey);
|
|
594
|
+
}
|
|
595
|
+
if (ctx.options.rejectDuplicateKeys) {
|
|
596
|
+
const seen = /* @__PURE__ */ new Set();
|
|
597
|
+
const keysForDupCheck = preEncodedKeys ?? entries.map((e) => encodeValue(e[0], { ...ctx, depth: ctx.depth + 1 }));
|
|
598
|
+
for (const keyBytes of keysForDupCheck) {
|
|
599
|
+
const keyHex = bytesToHex(keyBytes);
|
|
600
|
+
if (seen.has(keyHex)) {
|
|
601
|
+
throw new Error("Duplicate map key detected");
|
|
602
|
+
}
|
|
603
|
+
seen.add(keyHex);
|
|
604
|
+
}
|
|
403
605
|
}
|
|
404
606
|
const header = encodeLengthHeader(5, entries.length);
|
|
405
607
|
const parts = [header];
|
|
@@ -410,10 +612,6 @@ function useCborCollectionEncoder(globalOptions) {
|
|
|
410
612
|
parts.push(encodedValue);
|
|
411
613
|
}
|
|
412
614
|
const result = concatenateUint8Arrays(parts);
|
|
413
|
-
ctx.bytesWritten += result.length;
|
|
414
|
-
if (ctx.bytesWritten > ctx.options.maxOutputSize) {
|
|
415
|
-
throw new Error("Encoded output exceeds maximum size");
|
|
416
|
-
}
|
|
417
615
|
return {
|
|
418
616
|
bytes: result,
|
|
419
617
|
hex: bytesToHex(result)
|
|
@@ -422,6 +620,9 @@ function useCborCollectionEncoder(globalOptions) {
|
|
|
422
620
|
const encodeMap = (map, encodeOptions) => {
|
|
423
621
|
const isIndefinite = map[chunkPD72MVTX_cjs.INDEFINITE_SYMBOL] === true;
|
|
424
622
|
if (encodeOptions?.indefinite || isIndefinite) {
|
|
623
|
+
if (options.allowIndefinite === false) {
|
|
624
|
+
throw new Error("Indefinite-length encoding is not allowed");
|
|
625
|
+
}
|
|
425
626
|
if (options.canonical) {
|
|
426
627
|
throw new Error("Indefinite-length encoding not allowed in canonical mode");
|
|
427
628
|
}
|
|
@@ -429,12 +630,14 @@ function useCborCollectionEncoder(globalOptions) {
|
|
|
429
630
|
}
|
|
430
631
|
const ctx = {
|
|
431
632
|
depth: 0,
|
|
432
|
-
bytesWritten: 0,
|
|
433
633
|
options
|
|
434
634
|
};
|
|
435
635
|
return encodeMapInternal(map, ctx);
|
|
436
636
|
};
|
|
437
637
|
const encodeMapIndefinite = (map) => {
|
|
638
|
+
if (options.allowIndefinite === false) {
|
|
639
|
+
throw new Error("Indefinite-length encoding is not allowed");
|
|
640
|
+
}
|
|
438
641
|
if (options.canonical) {
|
|
439
642
|
throw new Error("Indefinite-length encoding not allowed in canonical mode");
|
|
440
643
|
}
|
|
@@ -442,7 +645,6 @@ function useCborCollectionEncoder(globalOptions) {
|
|
|
442
645
|
const parts = [new Uint8Array([191])];
|
|
443
646
|
const ctx = {
|
|
444
647
|
depth: 0,
|
|
445
|
-
bytesWritten: 0,
|
|
446
648
|
options
|
|
447
649
|
};
|
|
448
650
|
for (const [key, value] of entries) {
|
|
@@ -467,145 +669,6 @@ function useCborCollectionEncoder(globalOptions) {
|
|
|
467
669
|
};
|
|
468
670
|
}
|
|
469
671
|
|
|
470
|
-
// src/encoder/composables/useCborSimpleEncoder.ts
|
|
471
|
-
function useCborSimpleEncoder(_globalOptions) {
|
|
472
|
-
const { encodeInteger } = useCborIntegerEncoder();
|
|
473
|
-
const encodeSimple = (value) => {
|
|
474
|
-
let byte;
|
|
475
|
-
if (value === false) {
|
|
476
|
-
byte = 244;
|
|
477
|
-
} else if (value === true) {
|
|
478
|
-
byte = 245;
|
|
479
|
-
} else if (value === null) {
|
|
480
|
-
byte = 246;
|
|
481
|
-
} else if (value === void 0) {
|
|
482
|
-
byte = 247;
|
|
483
|
-
} else {
|
|
484
|
-
throw new Error(`Unsupported simple value: ${value}`);
|
|
485
|
-
}
|
|
486
|
-
return {
|
|
487
|
-
bytes: new Uint8Array([byte]),
|
|
488
|
-
hex: bytesToHex(new Uint8Array([byte]))
|
|
489
|
-
};
|
|
490
|
-
};
|
|
491
|
-
const encodeFloat16Bytes = (value) => {
|
|
492
|
-
if (value === 0) return new Uint8Array([0, 0]);
|
|
493
|
-
if (value === -0) return new Uint8Array([128, 0]);
|
|
494
|
-
if (Number.isNaN(value)) return new Uint8Array([126, 0]);
|
|
495
|
-
if (value === Infinity) return new Uint8Array([124, 0]);
|
|
496
|
-
if (value === -Infinity) return new Uint8Array([252, 0]);
|
|
497
|
-
const sign = value < 0 ? 1 : 0;
|
|
498
|
-
const absValue = Math.abs(value);
|
|
499
|
-
const buffer = new ArrayBuffer(8);
|
|
500
|
-
const view = new DataView(buffer);
|
|
501
|
-
view.setFloat64(0, absValue, false);
|
|
502
|
-
const bits = view.getBigUint64(0, false);
|
|
503
|
-
const exp64 = Number(bits >> 52n & 0x7ffn) - 1023;
|
|
504
|
-
const mant64 = Number(bits & 0xfffffffffffffn);
|
|
505
|
-
let exp16;
|
|
506
|
-
let mant16;
|
|
507
|
-
if (exp64 < -14) {
|
|
508
|
-
exp16 = 0;
|
|
509
|
-
mant16 = 0;
|
|
510
|
-
} else if (exp64 > 15) {
|
|
511
|
-
exp16 = 31;
|
|
512
|
-
mant16 = 0;
|
|
513
|
-
} else {
|
|
514
|
-
exp16 = exp64 + 15;
|
|
515
|
-
mant16 = mant64 >> 42;
|
|
516
|
-
}
|
|
517
|
-
const float16 = sign << 15 | exp16 << 10 | mant16;
|
|
518
|
-
return new Uint8Array([
|
|
519
|
-
float16 >> 8 & 255,
|
|
520
|
-
float16 & 255
|
|
521
|
-
]);
|
|
522
|
-
};
|
|
523
|
-
const encodeFloat32Bytes = (value) => {
|
|
524
|
-
const buffer = new ArrayBuffer(4);
|
|
525
|
-
const view = new DataView(buffer);
|
|
526
|
-
view.setFloat32(0, value, false);
|
|
527
|
-
return new Uint8Array(buffer);
|
|
528
|
-
};
|
|
529
|
-
const encodeFloat64Bytes = (value) => {
|
|
530
|
-
const buffer = new ArrayBuffer(8);
|
|
531
|
-
const view = new DataView(buffer);
|
|
532
|
-
view.setFloat64(0, value, false);
|
|
533
|
-
return new Uint8Array(buffer);
|
|
534
|
-
};
|
|
535
|
-
const canBeFloat16 = (value) => {
|
|
536
|
-
if (!Number.isFinite(value) || value === 0 || value === -0) {
|
|
537
|
-
return true;
|
|
538
|
-
}
|
|
539
|
-
const absValue = Math.abs(value);
|
|
540
|
-
if (absValue < 6103515625e-14 || absValue > 65504) {
|
|
541
|
-
return false;
|
|
542
|
-
}
|
|
543
|
-
const bytes = encodeFloat16Bytes(value);
|
|
544
|
-
const view = new DataView(bytes.buffer);
|
|
545
|
-
const bits = view.getUint16(0, false);
|
|
546
|
-
const sign = bits >> 15 & 1;
|
|
547
|
-
const exp = bits >> 10 & 31;
|
|
548
|
-
const mant = bits & 1023;
|
|
549
|
-
let decoded;
|
|
550
|
-
if (exp === 0) {
|
|
551
|
-
decoded = (sign ? -1 : 1) * Math.pow(2, -14) * (mant / 1024);
|
|
552
|
-
} else if (exp === 31) {
|
|
553
|
-
decoded = mant === 0 ? sign ? -Infinity : Infinity : NaN;
|
|
554
|
-
} else {
|
|
555
|
-
decoded = (sign ? -1 : 1) * Math.pow(2, exp - 15) * (1 + mant / 1024);
|
|
556
|
-
}
|
|
557
|
-
return decoded === value;
|
|
558
|
-
};
|
|
559
|
-
const canBeFloat32 = (value) => {
|
|
560
|
-
if (!Number.isFinite(value) || value === 0 || value === -0) {
|
|
561
|
-
return true;
|
|
562
|
-
}
|
|
563
|
-
const buffer = new ArrayBuffer(4);
|
|
564
|
-
const view = new DataView(buffer);
|
|
565
|
-
view.setFloat32(0, value, false);
|
|
566
|
-
const decoded = view.getFloat32(0, false);
|
|
567
|
-
return decoded === value;
|
|
568
|
-
};
|
|
569
|
-
const isInteger = (value) => {
|
|
570
|
-
return Number.isInteger(value) && Number.isSafeInteger(value);
|
|
571
|
-
};
|
|
572
|
-
const encodeFloat = (value, precision) => {
|
|
573
|
-
let bytes;
|
|
574
|
-
if (isInteger(value) && !precision) {
|
|
575
|
-
return encodeInteger(value);
|
|
576
|
-
}
|
|
577
|
-
if (precision === 16) {
|
|
578
|
-
const floatBytes = encodeFloat16Bytes(value);
|
|
579
|
-
bytes = new Uint8Array([249, ...floatBytes]);
|
|
580
|
-
} else if (precision === 32) {
|
|
581
|
-
const floatBytes = encodeFloat32Bytes(value);
|
|
582
|
-
bytes = new Uint8Array([250, ...floatBytes]);
|
|
583
|
-
} else if (precision === 64) {
|
|
584
|
-
const floatBytes = encodeFloat64Bytes(value);
|
|
585
|
-
bytes = new Uint8Array([251, ...floatBytes]);
|
|
586
|
-
} else {
|
|
587
|
-
if (canBeFloat16(value)) {
|
|
588
|
-
const floatBytes = encodeFloat16Bytes(value);
|
|
589
|
-
bytes = new Uint8Array([249, ...floatBytes]);
|
|
590
|
-
} else if (canBeFloat32(value)) {
|
|
591
|
-
const floatBytes = encodeFloat32Bytes(value);
|
|
592
|
-
bytes = new Uint8Array([250, ...floatBytes]);
|
|
593
|
-
} else {
|
|
594
|
-
const floatBytes = encodeFloat64Bytes(value);
|
|
595
|
-
bytes = new Uint8Array([251, ...floatBytes]);
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
|
-
return {
|
|
599
|
-
bytes,
|
|
600
|
-
hex: bytesToHex(bytes)
|
|
601
|
-
};
|
|
602
|
-
};
|
|
603
|
-
return {
|
|
604
|
-
encodeSimple,
|
|
605
|
-
encodeFloat
|
|
606
|
-
};
|
|
607
|
-
}
|
|
608
|
-
|
|
609
672
|
// src/encoder/composables/useCborTagEncoder.ts
|
|
610
673
|
function useCborTagEncoder() {
|
|
611
674
|
const encodeTagNumber = (tagNumber) => {
|
|
@@ -659,6 +722,9 @@ function useCborTagEncoder() {
|
|
|
659
722
|
// src/encoder/composables/useCborEncoder.ts
|
|
660
723
|
function useCborEncoder(globalOptions) {
|
|
661
724
|
const options = { ...DEFAULT_ENCODE_OPTIONS, ...globalOptions };
|
|
725
|
+
if (options.canonical && options.allowIndefinite) {
|
|
726
|
+
options.allowIndefinite = false;
|
|
727
|
+
}
|
|
662
728
|
const { encodeInteger } = useCborIntegerEncoder();
|
|
663
729
|
const { encodeTextString, encodeByteString } = useCborStringEncoder(options);
|
|
664
730
|
const { encodeArray, encodeMap, setMainEncode } = useCborCollectionEncoder(options);
|
|
@@ -667,11 +733,23 @@ function useCborEncoder(globalOptions) {
|
|
|
667
733
|
const { isCborByteString } = chunkPD72MVTX_cjs.useCborByteString();
|
|
668
734
|
const { isCborTextString } = chunkPD72MVTX_cjs.useCborTextString();
|
|
669
735
|
const encode = (value) => {
|
|
736
|
+
const result = encodeValue(value);
|
|
737
|
+
if (options.maxOutputSize && result.bytes.length > options.maxOutputSize) {
|
|
738
|
+
throw new Error(
|
|
739
|
+
`Encoded output size ${result.bytes.length} bytes exceeds limit of ${options.maxOutputSize} bytes`
|
|
740
|
+
);
|
|
741
|
+
}
|
|
742
|
+
return result;
|
|
743
|
+
};
|
|
744
|
+
const encodeValue = (value) => {
|
|
670
745
|
if (value === null || value === void 0 || typeof value === "boolean") {
|
|
671
746
|
return encodeSimple(value);
|
|
672
747
|
}
|
|
673
748
|
if (typeof value === "number") {
|
|
674
|
-
if (
|
|
749
|
+
if (Object.is(value, -0)) {
|
|
750
|
+
return encodeFloat(value, 16);
|
|
751
|
+
}
|
|
752
|
+
if (Number.isSafeInteger(value)) {
|
|
675
753
|
return encodeInteger(value);
|
|
676
754
|
}
|
|
677
755
|
return encodeFloat(value);
|
|
@@ -751,5 +829,5 @@ exports.useCborStringEncoder = useCborStringEncoder;
|
|
|
751
829
|
exports.useCborTagEncoder = useCborTagEncoder;
|
|
752
830
|
exports.writeBigUint = writeBigUint;
|
|
753
831
|
exports.writeUint = writeUint;
|
|
754
|
-
//# sourceMappingURL=chunk-
|
|
755
|
-
//# sourceMappingURL=chunk-
|
|
832
|
+
//# sourceMappingURL=chunk-S4RXO6IB.cjs.map
|
|
833
|
+
//# sourceMappingURL=chunk-S4RXO6IB.cjs.map
|