@haneullabs/bcs 2.0.3 → 2.1.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"writer.mjs","names":[],"sources":["../src/writer.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { Encoding } from './types.js';\nimport { ulebEncode } from './uleb.js';\nimport { encodeStr } from './utils.js';\n\nexport interface BcsWriterOptions {\n\t/** The initial size (in bytes) of the buffer tht will be allocated */\n\tinitialSize?: number;\n\t/** The maximum size (in bytes) that the buffer is allowed to grow to */\n\tmaxSize?: number;\n\t/** The amount of bytes that will be allocated whenever additional memory is required */\n\tallocateSize?: number;\n}\n\n/**\n * Class used to write BCS data into a buffer. Initializer requires\n * some size of a buffer to init; default value for this buffer is 1KB.\n *\n * Most methods are chainable, so it is possible to write them in one go.\n *\n * @example\n * let serialized = new BcsWriter()\n * .write8(10)\n * .write32(1000000)\n * .write64(10000001000000)\n * .hex();\n */\n\n/**\n * Set of methods that allows data encoding/decoding as standalone\n * BCS value or a part of a composed structure/vector.\n */\nexport class BcsWriter {\n\tprivate dataView: DataView<ArrayBuffer>;\n\tprivate bytePosition: number = 0;\n\tprivate size: number;\n\tprivate maxSize: number;\n\tprivate allocateSize: number;\n\n\tconstructor({\n\t\tinitialSize = 1024,\n\t\tmaxSize = Infinity,\n\t\tallocateSize = 1024,\n\t}: BcsWriterOptions = {}) {\n\t\tthis.size = initialSize;\n\t\tthis.maxSize = maxSize;\n\t\tthis.allocateSize = allocateSize;\n\t\tthis.dataView = new DataView(new ArrayBuffer(initialSize));\n\t}\n\n\tprivate ensureSizeOrGrow(bytes: number) {\n\t\tconst requiredSize = this.bytePosition + bytes;\n\t\tif (requiredSize > this.size) {\n\t\t\tconst nextSize = Math.min(\n\t\t\t\tthis.maxSize,\n\t\t\t\tMath.max(this.size + requiredSize, this.size + this.allocateSize),\n\t\t\t);\n\t\t\tif (requiredSize > nextSize) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Attempting to serialize to BCS, but buffer does not have enough size. Allocated size: ${this.size}, Max size: ${this.maxSize}, Required size: ${requiredSize}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tthis.size = nextSize;\n\t\t\tconst nextBuffer = new ArrayBuffer(this.size);\n\t\t\tnew Uint8Array(nextBuffer).set(new Uint8Array(this.dataView.buffer));\n\t\t\tthis.dataView = new DataView(nextBuffer);\n\t\t}\n\t}\n\n\t/**\n\t * Shift current cursor position by `bytes`.\n\t *\n\t * @param {Number} bytes Number of bytes to\n\t * @returns {this} Self for possible chaining.\n\t */\n\tshift(bytes: number): this {\n\t\tthis.bytePosition += bytes;\n\t\treturn this;\n\t}\n\t/**\n\t * Write a U8 value into a buffer and shift cursor position by 1.\n\t * @param {Number} value Value to write.\n\t * @returns {this}\n\t */\n\twrite8(value: number | bigint): this {\n\t\tthis.ensureSizeOrGrow(1);\n\t\tthis.dataView.setUint8(this.bytePosition, Number(value));\n\t\treturn this.shift(1);\n\t}\n\n\t/**\n\t * Write a U8 value into a buffer and shift cursor position by 1.\n\t * @param {Number} value Value to write.\n\t * @returns {this}\n\t */\n\twriteBytes(bytes: Uint8Array): this {\n\t\tthis.ensureSizeOrGrow(bytes.length);\n\n\t\tfor (let i = 0; i < bytes.length; i++) {\n\t\t\tthis.dataView.setUint8(this.bytePosition + i, bytes[i]);\n\t\t}\n\n\t\treturn this.shift(bytes.length);\n\t}\n\t/**\n\t * Write a U16 value into a buffer and shift cursor position by 2.\n\t * @param {Number} value Value to write.\n\t * @returns {this}\n\t */\n\twrite16(value: number | bigint): this {\n\t\tthis.ensureSizeOrGrow(2);\n\t\tthis.dataView.setUint16(this.bytePosition, Number(value), true);\n\t\treturn this.shift(2);\n\t}\n\t/**\n\t * Write a U32 value into a buffer and shift cursor position by 4.\n\t * @param {Number} value Value to write.\n\t * @returns {this}\n\t */\n\twrite32(value: number | bigint): this {\n\t\tthis.ensureSizeOrGrow(4);\n\t\tthis.dataView.setUint32(this.bytePosition, Number(value), true);\n\t\treturn this.shift(4);\n\t}\n\t/**\n\t * Write a U64 value into a buffer and shift cursor position by 8.\n\t * @param {bigint} value Value to write.\n\t * @returns {this}\n\t */\n\twrite64(value: number | bigint): this {\n\t\ttoLittleEndian(BigInt(value), 8).forEach((el) => this.write8(el));\n\n\t\treturn this;\n\t}\n\t/**\n\t * Write a U128 value into a buffer and shift cursor position by 16.\n\t *\n\t * @param {bigint} value Value to write.\n\t * @returns {this}\n\t */\n\twrite128(value: number | bigint): this {\n\t\ttoLittleEndian(BigInt(value), 16).forEach((el) => this.write8(el));\n\n\t\treturn this;\n\t}\n\t/**\n\t * Write a U256 value into a buffer and shift cursor position by 16.\n\t *\n\t * @param {bigint} value Value to write.\n\t * @returns {this}\n\t */\n\twrite256(value: number | bigint): this {\n\t\ttoLittleEndian(BigInt(value), 32).forEach((el) => this.write8(el));\n\n\t\treturn this;\n\t}\n\t/**\n\t * Write a ULEB value into a buffer and shift cursor position by number of bytes\n\t * written.\n\t * @param {Number} value Value to write.\n\t * @returns {this}\n\t */\n\twriteULEB(value: number): this {\n\t\tulebEncode(value).forEach((el) => this.write8(el));\n\t\treturn this;\n\t}\n\t/**\n\t * Write a vector into a buffer by first writing the vector length and then calling\n\t * a callback on each passed value.\n\t *\n\t * @param {Array<Any>} vector Array of elements to write.\n\t * @param {WriteVecCb} cb Callback to call on each element of the vector.\n\t * @returns {this}\n\t */\n\twriteVec(vector: any[], cb: (writer: BcsWriter, el: any, i: number, len: number) => void): this {\n\t\tthis.writeULEB(vector.length);\n\t\tArray.from(vector).forEach((el, i) => cb(this, el, i, vector.length));\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds support for iterations over the object.\n\t * @returns {Uint8Array}\n\t */\n\t// oxlint-disable-next-line require-yields\n\t*[Symbol.iterator](): Iterator<number, Iterable<number>> {\n\t\tfor (let i = 0; i < this.bytePosition; i++) {\n\t\t\tyield this.dataView.getUint8(i);\n\t\t}\n\t\treturn this.toBytes();\n\t}\n\n\t/**\n\t * Get underlying buffer taking only value bytes (in case initial buffer size was bigger).\n\t * @returns {Uint8Array} Resulting bcs.\n\t */\n\ttoBytes(): Uint8Array<ArrayBuffer> {\n\t\treturn new Uint8Array(this.dataView.buffer.slice(0, this.bytePosition));\n\t}\n\n\t/**\n\t * Represent data as 'hex' or 'base64'\n\t * @param encoding Encoding to use: 'base64' or 'hex'\n\t */\n\ttoString(encoding: Encoding): string {\n\t\treturn encodeStr(this.toBytes(), encoding);\n\t}\n}\n\nfunction toLittleEndian(bigint: bigint, size: number) {\n\tconst result = new Uint8Array(size);\n\tlet i = 0;\n\twhile (bigint > 0) {\n\t\tresult[i] = Number(bigint % BigInt(256));\n\t\tbigint = bigint / BigInt(256);\n\t\ti += 1;\n\t}\n\treturn result;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"writer.mjs","names":[],"sources":["../src/writer.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { Encoding } from './types.js';\nimport { ulebEncode } from './uleb.js';\nimport { encodeStr } from './utils.js';\n\nexport interface BcsWriterOptions {\n\t/** The initial size (in bytes) of the buffer tht will be allocated */\n\tinitialSize?: number;\n\t/** The maximum size (in bytes) that the buffer is allowed to grow to */\n\tmaxSize?: number;\n\t/** The amount of bytes that will be allocated whenever additional memory is required */\n\tallocateSize?: number;\n}\n\n/**\n * Class used to write BCS data into a buffer. Initializer requires\n * some size of a buffer to init; default value for this buffer is 1KB.\n *\n * Most methods are chainable, so it is possible to write them in one go.\n *\n * @example\n * let serialized = new BcsWriter()\n * .write8(10)\n * .write32(1000000)\n * .write64(10000001000000)\n * .hex();\n */\n\n/**\n * Set of methods that allows data encoding/decoding as standalone\n * BCS value or a part of a composed structure/vector.\n */\nexport class BcsWriter {\n\tprivate dataView: DataView<ArrayBuffer>;\n\tprivate bytePosition: number = 0;\n\tprivate size: number;\n\tprivate maxSize: number;\n\tprivate allocateSize: number;\n\n\tconstructor({\n\t\tinitialSize = 1024,\n\t\tmaxSize = Infinity,\n\t\tallocateSize = 1024,\n\t}: BcsWriterOptions = {}) {\n\t\tthis.size = initialSize;\n\t\tthis.maxSize = maxSize;\n\t\tthis.allocateSize = allocateSize;\n\t\tthis.dataView = new DataView(new ArrayBuffer(initialSize));\n\t}\n\n\tprivate ensureSizeOrGrow(bytes: number) {\n\t\tconst requiredSize = this.bytePosition + bytes;\n\t\tif (requiredSize > this.size) {\n\t\t\tconst nextSize = Math.min(\n\t\t\t\tthis.maxSize,\n\t\t\t\tMath.max(this.size + requiredSize, this.size + this.allocateSize),\n\t\t\t);\n\t\t\tif (requiredSize > nextSize) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Attempting to serialize to BCS, but buffer does not have enough size. Allocated size: ${this.size}, Max size: ${this.maxSize}, Required size: ${requiredSize}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tthis.size = nextSize;\n\t\t\tconst nextBuffer = new ArrayBuffer(this.size);\n\t\t\tnew Uint8Array(nextBuffer).set(new Uint8Array(this.dataView.buffer));\n\t\t\tthis.dataView = new DataView(nextBuffer);\n\t\t}\n\t}\n\n\t/**\n\t * Shift current cursor position by `bytes`.\n\t *\n\t * @param {Number} bytes Number of bytes to\n\t * @returns {this} Self for possible chaining.\n\t */\n\tshift(bytes: number): this {\n\t\tthis.bytePosition += bytes;\n\t\treturn this;\n\t}\n\t/**\n\t * Write a U8 value into a buffer and shift cursor position by 1.\n\t * @param {Number} value Value to write.\n\t * @returns {this}\n\t */\n\twrite8(value: number | bigint): this {\n\t\tthis.ensureSizeOrGrow(1);\n\t\tthis.dataView.setUint8(this.bytePosition, Number(value));\n\t\treturn this.shift(1);\n\t}\n\n\t/**\n\t * Write a U8 value into a buffer and shift cursor position by 1.\n\t * @param {Number} value Value to write.\n\t * @returns {this}\n\t */\n\twriteBytes(bytes: Uint8Array): this {\n\t\tthis.ensureSizeOrGrow(bytes.length);\n\n\t\tfor (let i = 0; i < bytes.length; i++) {\n\t\t\tthis.dataView.setUint8(this.bytePosition + i, bytes[i]);\n\t\t}\n\n\t\treturn this.shift(bytes.length);\n\t}\n\t/**\n\t * Write a U16 value into a buffer and shift cursor position by 2.\n\t * @param {Number} value Value to write.\n\t * @returns {this}\n\t */\n\twrite16(value: number | bigint): this {\n\t\tthis.ensureSizeOrGrow(2);\n\t\tthis.dataView.setUint16(this.bytePosition, Number(value), true);\n\t\treturn this.shift(2);\n\t}\n\t/**\n\t * Write a U32 value into a buffer and shift cursor position by 4.\n\t * @param {Number} value Value to write.\n\t * @returns {this}\n\t */\n\twrite32(value: number | bigint): this {\n\t\tthis.ensureSizeOrGrow(4);\n\t\tthis.dataView.setUint32(this.bytePosition, Number(value), true);\n\t\treturn this.shift(4);\n\t}\n\t/**\n\t * Write a U64 value into a buffer and shift cursor position by 8.\n\t * @param {bigint} value Value to write.\n\t * @returns {this}\n\t */\n\twrite64(value: number | bigint): this {\n\t\ttoLittleEndian(BigInt(value), 8).forEach((el) => this.write8(el));\n\n\t\treturn this;\n\t}\n\t/**\n\t * Write a U128 value into a buffer and shift cursor position by 16.\n\t *\n\t * @param {bigint} value Value to write.\n\t * @returns {this}\n\t */\n\twrite128(value: number | bigint): this {\n\t\ttoLittleEndian(BigInt(value), 16).forEach((el) => this.write8(el));\n\n\t\treturn this;\n\t}\n\t/**\n\t * Write a U256 value into a buffer and shift cursor position by 16.\n\t *\n\t * @param {bigint} value Value to write.\n\t * @returns {this}\n\t */\n\twrite256(value: number | bigint): this {\n\t\ttoLittleEndian(BigInt(value), 32).forEach((el) => this.write8(el));\n\n\t\treturn this;\n\t}\n\t/**\n\t * Write a ULEB value into a buffer and shift cursor position by number of bytes\n\t * written.\n\t * @param {Number} value Value to write.\n\t * @returns {this}\n\t */\n\twriteULEB(value: number): this {\n\t\tulebEncode(value).forEach((el) => this.write8(el));\n\t\treturn this;\n\t}\n\t/**\n\t * Write a vector into a buffer by first writing the vector length and then calling\n\t * a callback on each passed value.\n\t *\n\t * @param {Array<Any>} vector Array of elements to write.\n\t * @param {WriteVecCb} cb Callback to call on each element of the vector.\n\t * @returns {this}\n\t */\n\twriteVec(vector: any[], cb: (writer: BcsWriter, el: any, i: number, len: number) => void): this {\n\t\tthis.writeULEB(vector.length);\n\t\tArray.from(vector).forEach((el, i) => cb(this, el, i, vector.length));\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds support for iterations over the object.\n\t * @returns {Uint8Array}\n\t */\n\t// oxlint-disable-next-line require-yields\n\t*[Symbol.iterator](): Iterator<number, Iterable<number>> {\n\t\tfor (let i = 0; i < this.bytePosition; i++) {\n\t\t\tyield this.dataView.getUint8(i);\n\t\t}\n\t\treturn this.toBytes();\n\t}\n\n\t/**\n\t * Get underlying buffer taking only value bytes (in case initial buffer size was bigger).\n\t * @returns {Uint8Array} Resulting bcs.\n\t */\n\ttoBytes(): Uint8Array<ArrayBuffer> {\n\t\treturn new Uint8Array(this.dataView.buffer.slice(0, this.bytePosition));\n\t}\n\n\t/**\n\t * Represent data as 'hex' or 'base64'\n\t * @param encoding Encoding to use: 'base64' or 'hex'\n\t */\n\ttoString(encoding: Encoding): string {\n\t\treturn encodeStr(this.toBytes(), encoding);\n\t}\n}\n\nfunction toLittleEndian(bigint: bigint, size: number) {\n\tconst result = new Uint8Array(size);\n\tlet i = 0;\n\twhile (bigint > 0) {\n\t\tresult[i] = Number(bigint % BigInt(256));\n\t\tbigint = bigint / BigInt(256);\n\t\ti += 1;\n\t}\n\treturn result;\n}\n"],"mappings":"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"}
package/docs/index.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # BCS - Binary Canonical Serialization
2
2
 
3
- > Encode and decode Haneul Move types with Binary Canonical Serialization
3
+ > Encode and decode Haneul Move types with Binary Canonical Serialization.
4
4
 
5
5
  This small and lightweight library implements
6
6
  [Binary Canonical Serialization (BCS)](https://github.com/zefchain/bcs) in TypeScript, making BCS
@@ -8,16 +8,17 @@ available in both Browser and NodeJS environments in a type-safe way.`
8
8
 
9
9
  ## Install
10
10
 
11
- To install, add the [`@haneullabs/bcs`](https://www.npmjs.com/package/@haneullabs/bcs) package to
12
- your project:
11
+ To install, add the [`@haneullabs/bcs`](https://www.npmjs.com/package/@haneullabs/bcs) package to your
12
+ project:
13
13
 
14
- ```sh npm2yarn
14
+ ```npm
15
15
  npm i @haneullabs/bcs
16
16
  ```
17
17
 
18
18
  ## Quickstart
19
19
 
20
20
  ```ts
21
+
21
22
  // define UID as a 32-byte array, then add a transform to/from hex strings
22
23
  const UID = bcs.fixedArray(32, bcs.u8()).transform({
23
24
  input: (id: string) => fromHex(id),
@@ -70,6 +71,7 @@ following table lists the primitive types available:
70
71
  | `byteVector` | `Uint8Array` | `Iterable<number>` | Variable length bytes |
71
72
 
72
73
  ```ts
74
+
73
75
  // Integers
74
76
  const u8 = bcs.u8().serialize(100).toBytes();
75
77
  const u64 = bcs.u64().serialize(1000000n).toBytes();
@@ -111,6 +113,7 @@ For most use-cases you'll want to combine primitive types into more complex type
111
113
  | `map(K, V)` | A map of keys of type `K` to values of type `V` |
112
114
 
113
115
  ```ts
116
+
114
117
  // Vectors
115
118
  const intList = bcs.vector(bcs.u8()).serialize([1, 2, 3, 4, 5]).toBytes();
116
119
  const stringList = bcs.vector(bcs.string()).serialize(['a', 'b', 'c']).toBytes();
@@ -242,6 +245,7 @@ represent an address as a hex string, but the BCS serialization format for addre
242
245
  array. To handle this, you can use the `transform` API to map between the two formats:
243
246
 
244
247
  ```ts
248
+
245
249
  const Address = bcs.bytes(32).transform({
246
250
  // To change the input type, you need to provide a type definition for the input
247
251
  input: (val: string) => fromHex(val),
@@ -306,6 +310,7 @@ preserves type information for the serialized bytes, and can be used to get raw
306
310
  formats.
307
311
 
308
312
  ```ts
313
+
309
314
  const serializedString = bcs.string().serialize('this is a string');
310
315
 
311
316
  // SerializedBcs.toBytes() returns a Uint8Array
@@ -337,6 +342,7 @@ You can infer these types in one of 2 ways, either using the `$inferType` and `$
337
342
  properties on a `BcsType`, or using the `InferBcsType` and `InferBcsInput` type helpers.
338
343
 
339
344
  ```ts
345
+
340
346
  const MyStruct = bcs.struct('MyStruct', {
341
347
  id: bcs.u64(),
342
348
  name: bcs.string(),
@@ -349,4 +355,4 @@ type MyStructInput = typeof MyStruct.$inferInput; // { id: number | string | big
349
355
  // using the InferBcsType and InferBcsInput type helpers
350
356
  type MyStructType = InferBcsType<typeof MyStruct>; // { id: string; name: string; }
351
357
  type MyStructInput = InferBcsInput<typeof MyStruct>; // { id: number | string | bigint; name: string; }
352
- ```
358
+ ```
@@ -1,6 +1,4 @@
1
1
  # BCS
2
-
3
2
  > Encoding and decoding Haneul objects
4
3
 
5
- - [BCS - Binary Canonical Serialization](./index.md): Encode and decode Haneul Move types with
6
- Binary Canonical Serialization
4
+ - [BCS - Binary Canonical Serialization](..md): Encode and decode Haneul Move types with Binary Canonical Serialization.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haneullabs/bcs",
3
- "version": "2.0.3",
3
+ "version": "2.1.2",
4
4
  "description": "BCS - Canonical Binary Serialization implementation for JavaScript",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Haneul Labs <build@haneul-labs.com>",
@@ -23,7 +23,7 @@
23
23
  ],
24
24
  "repository": {
25
25
  "type": "git",
26
- "url": "git+https://github.com/GeunhwaJeong/ts-sdks.git"
26
+ "url": "git+https://github.com/GeunhwaJeong/haneul-ts-sdks.git"
27
27
  },
28
28
  "keywords": [
29
29
  "bcs",
@@ -34,7 +34,7 @@
34
34
  "serde"
35
35
  ],
36
36
  "bugs": {
37
- "url": "https://github.com/GeunhwaJeong/ts-sdks/issues"
37
+ "url": "https://github.com/GeunhwaJeong/haneul-ts-sdks/issues"
38
38
  },
39
39
  "size-limit": [
40
40
  {
@@ -44,19 +44,19 @@
44
44
  ],
45
45
  "homepage": "https://sdk.haneul-labs.com/bcs",
46
46
  "devDependencies": {
47
- "@size-limit/preset-small-lib": "^12.0.0",
48
- "size-limit": "^12.0.0",
49
- "typescript": "^5.9.3",
50
- "vitest": "^4.0.17"
47
+ "@size-limit/preset-small-lib": "^13.0.3",
48
+ "size-limit": "^13.0.3",
49
+ "typescript": "^7.0.2",
50
+ "vitest": "^4.1.11"
51
51
  },
52
52
  "dependencies": {
53
- "@scure/base": "^2.0.0",
54
- "@haneullabs/utils": "^0.3.2"
53
+ "@scure/base": "^2.3.0",
54
+ "@haneullabs/utils": "^0.4.1"
55
55
  },
56
56
  "scripts": {
57
57
  "clean": "rm -rf tsconfig.tsbuildinfo ./dist",
58
58
  "build": "rm -rf dist && tsc --noEmit && tsdown",
59
- "build:docs": "tsx ../docs/scripts/build-docs.ts",
59
+ "build:docs": "node ../docs/scripts/build-docs.ts",
60
60
  "test": "vitest run --typecheck",
61
61
  "test:watch": "vitest --typecheck",
62
62
  "prettier:check": "prettier -c --ignore-unknown .",
package/src/bcs.ts CHANGED
@@ -316,7 +316,13 @@ export const bcs = {
316
316
  bool(options?: BcsTypeOptions<boolean>) {
317
317
  return fixedSizeBcsType({
318
318
  size: 1,
319
- read: (reader) => reader.read8() === 1,
319
+ read: (reader) => {
320
+ const value = reader.read8();
321
+ if (value > 1) {
322
+ throw new TypeError(`Invalid bool value: expected 0 or 1, found ${value}`);
323
+ }
324
+ return value === 1;
325
+ },
320
326
  write: (value, writer) => writer.write8(value ? 1 : 0),
321
327
  ...options,
322
328
  name: (options?.name ?? 'bool') as 'bool',
@@ -413,7 +419,8 @@ export const bcs = {
413
419
  string(options?: BcsTypeOptions<string>) {
414
420
  return stringLikeBcsType({
415
421
  toBytes: (value) => new TextEncoder().encode(value),
416
- fromBytes: (bytes) => new TextDecoder().decode(bytes),
422
+ fromBytes: (bytes) =>
423
+ new TextDecoder('utf-8', { fatal: true, ignoreBOM: true }).decode(bytes),
417
424
  ...options,
418
425
  name: (options?.name ?? 'string') as 'string',
419
426
  });
package/src/uleb.ts CHANGED
@@ -43,6 +43,10 @@ export function ulebDecode(arr: number[] | Uint8Array): {
43
43
  len += 1;
44
44
  total += BigInt(byte & 0x7f) << shift;
45
45
  if ((byte & 0x80) === 0) {
46
+ // A trailing zero group adds no value, so the encoding is not minimal
47
+ if (byte === 0 && len > 1) {
48
+ throw new Error('ULEB decode error: non-canonical encoding');
49
+ }
46
50
  break;
47
51
  }
48
52
  shift += 7n;