@marcuspuchalla/nachos 0.1.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.
- package/CHANGELOG.md +64 -0
- package/LICENSE +674 -0
- package/README.md +345 -0
- package/dist/chunk-2FUTHZQQ.cjs +755 -0
- package/dist/chunk-2FUTHZQQ.cjs.map +1 -0
- package/dist/chunk-2HBCILJS.cjs +2034 -0
- package/dist/chunk-2HBCILJS.cjs.map +1 -0
- package/dist/chunk-7CFYWHS6.js +742 -0
- package/dist/chunk-7CFYWHS6.js.map +1 -0
- package/dist/chunk-PD72MVTX.cjs +160 -0
- package/dist/chunk-PD72MVTX.cjs.map +1 -0
- package/dist/chunk-ZDZ2B5PE.js +149 -0
- package/dist/chunk-ZDZ2B5PE.js.map +1 -0
- package/dist/chunk-ZRPJUEIZ.js +2020 -0
- package/dist/chunk-ZRPJUEIZ.js.map +1 -0
- package/dist/encoder/index.cjs +57 -0
- package/dist/encoder/index.cjs.map +1 -0
- package/dist/encoder/index.d.cts +72 -0
- package/dist/encoder/index.d.ts +72 -0
- package/dist/encoder/index.js +4 -0
- package/dist/encoder/index.js.map +1 -0
- package/dist/index.cjs +606 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +494 -0
- package/dist/index.d.ts +494 -0
- package/dist/index.js +523 -0
- package/dist/index.js.map +1 -0
- package/dist/metafile-cjs.json +1 -0
- package/dist/metafile-esm.json +1 -0
- package/dist/parser/index.cjs +85 -0
- package/dist/parser/index.cjs.map +1 -0
- package/dist/parser/index.d.cts +72 -0
- package/dist/parser/index.d.ts +72 -0
- package/dist/parser/index.js +4 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/types-DvNlfbKB.d.cts +301 -0
- package/dist/types-DvNlfbKB.d.ts +301 -0
- package/dist/useCborSimpleEncoder-ButVU988.d.cts +268 -0
- package/dist/useCborSimpleEncoder-TVxzNJ_9.d.ts +268 -0
- package/dist/useCborTag-B_iaShG6.d.ts +142 -0
- package/dist/useCborTag-BfTIV8HM.d.cts +142 -0
- package/package.json +102 -0
- package/src/__tests__/public-api.test.ts +326 -0
- package/src/encoder/__tests__/cbor-collection-encoder.test.ts +331 -0
- package/src/encoder/__tests__/cbor-integer-encoder.test.ts +283 -0
- package/src/encoder/__tests__/cbor-simple-encoder.test.ts +224 -0
- package/src/encoder/__tests__/cbor-string-encoder.test.ts +345 -0
- package/src/encoder/__tests__/cbor-tag-encoder.test.ts +565 -0
- package/src/encoder/composables/#useCborTagEncoder.ts# +158 -0
- package/src/encoder/composables/useCborCollectionEncoder.ts +424 -0
- package/src/encoder/composables/useCborEncoder.ts +203 -0
- package/src/encoder/composables/useCborIntegerEncoder.ts +188 -0
- package/src/encoder/composables/useCborSimpleEncoder.ts +266 -0
- package/src/encoder/composables/useCborStringEncoder.ts +266 -0
- package/src/encoder/composables/useCborTagEncoder.ts +158 -0
- package/src/encoder/index.ts +35 -0
- package/src/encoder/types.ts +88 -0
- package/src/encoder/utils.ts +80 -0
- package/src/index.ts +434 -0
- package/src/parser/__tests__/ast-tree-structure.test.ts +311 -0
- package/src/parser/__tests__/cbor-collection-errors.test.ts +296 -0
- package/src/parser/__tests__/cbor-collection.test.ts +369 -0
- package/src/parser/__tests__/cbor-deterministic-encoding.test.ts +432 -0
- package/src/parser/__tests__/cbor-diagnostic.test.ts +333 -0
- package/src/parser/__tests__/cbor-duplicate-keys.test.ts +235 -0
- package/src/parser/__tests__/cbor-float-errors.test.ts +222 -0
- package/src/parser/__tests__/cbor-float.test.ts +502 -0
- package/src/parser/__tests__/cbor-integer-errors.test.ts +139 -0
- package/src/parser/__tests__/cbor-integer.test.ts +200 -0
- package/src/parser/__tests__/cbor-map-duplicate-keys.test.ts +403 -0
- package/src/parser/__tests__/cbor-parser-errors.test.ts +126 -0
- package/src/parser/__tests__/cbor-security-dos-protection.test.ts +503 -0
- package/src/parser/__tests__/cbor-sequences.test.ts +150 -0
- package/src/parser/__tests__/cbor-source-map.test.ts +321 -0
- package/src/parser/__tests__/cbor-standard-tags.test.ts +340 -0
- package/src/parser/__tests__/cbor-string-errors.test.ts +227 -0
- package/src/parser/__tests__/cbor-string.test.ts +224 -0
- package/src/parser/__tests__/cbor-tag-advanced.test.ts +500 -0
- package/src/parser/__tests__/cbor-tag-errors.test.ts +447 -0
- package/src/parser/__tests__/cbor-tag-source-map.test.ts +360 -0
- package/src/parser/__tests__/cbor-tag.test.ts +684 -0
- package/src/parser/__tests__/extreme-edge-cases.test.ts +146 -0
- package/src/parser/__tests__/pathBuilder.test.ts +256 -0
- package/src/parser/__tests__/rfc-test-vectors.test.ts +607 -0
- package/src/parser/__tests__/security-limits.test.ts +248 -0
- package/src/parser/__tests__/utils-errors.test.ts +127 -0
- package/src/parser/composables/useCborCollection.ts +509 -0
- package/src/parser/composables/useCborDiagnostic.ts +381 -0
- package/src/parser/composables/useCborFloat.ts +256 -0
- package/src/parser/composables/useCborInteger.ts +114 -0
- package/src/parser/composables/useCborParser.ts +951 -0
- package/src/parser/composables/useCborString.ts +330 -0
- package/src/parser/composables/useCborStringTypes.ts +129 -0
- package/src/parser/composables/useCborTag.ts +739 -0
- package/src/parser/index.ts +56 -0
- package/src/parser/types.ts +371 -0
- package/src/parser/utils/pathBuilder.ts +259 -0
- package/src/parser/utils.ts +398 -0
- package/src/utils/__tests__/logger.test.ts +186 -0
- package/src/utils/logger.ts +96 -0
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest'
|
|
2
|
+
import { validateUtf8Strict, validateCanonicalInteger, compareBytes } from '../utils'
|
|
3
|
+
|
|
4
|
+
describe('Security: UTF-8 Validation', () => {
|
|
5
|
+
describe('validateUtf8Strict - Valid UTF-8', () => {
|
|
6
|
+
it('should accept valid ASCII', () => {
|
|
7
|
+
const bytes = new Uint8Array([0x48, 0x65, 0x6c, 0x6c, 0x6f]) // "Hello"
|
|
8
|
+
expect(() => validateUtf8Strict(bytes)).not.toThrow()
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
it('should accept valid 2-byte sequences', () => {
|
|
12
|
+
const bytes = new Uint8Array([0xc3, 0xa9]) // "é" (U+00E9)
|
|
13
|
+
expect(() => validateUtf8Strict(bytes)).not.toThrow()
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
it('should accept valid 3-byte sequences', () => {
|
|
17
|
+
const bytes = new Uint8Array([0xe2, 0x82, 0xac]) // "€" (U+20AC)
|
|
18
|
+
expect(() => validateUtf8Strict(bytes)).not.toThrow()
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
it('should accept valid 4-byte sequences', () => {
|
|
22
|
+
const bytes = new Uint8Array([0xf0, 0x9f, 0x98, 0x80]) // "😀" (U+1F600)
|
|
23
|
+
expect(() => validateUtf8Strict(bytes)).not.toThrow()
|
|
24
|
+
})
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
describe('validateUtf8Strict - Invalid Start Bytes', () => {
|
|
28
|
+
it('should reject 0xC0 (invalid start byte)', () => {
|
|
29
|
+
const bytes = new Uint8Array([0xc0, 0x80])
|
|
30
|
+
expect(() => validateUtf8Strict(bytes)).toThrow(/Invalid UTF-8 start byte/)
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
it('should reject 0xC1 (invalid start byte)', () => {
|
|
34
|
+
const bytes = new Uint8Array([0xc1, 0x80])
|
|
35
|
+
expect(() => validateUtf8Strict(bytes)).toThrow(/Invalid UTF-8 start byte/)
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
it('should reject 0xF5-0xFF (invalid start bytes)', () => {
|
|
39
|
+
const bytes = new Uint8Array([0xf5, 0x80, 0x80, 0x80])
|
|
40
|
+
expect(() => validateUtf8Strict(bytes)).toThrow(/Invalid UTF-8 start byte/)
|
|
41
|
+
})
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
describe('validateUtf8Strict - Overlong Encodings', () => {
|
|
45
|
+
it('should reject overlong 2-byte encoding of "/" (security vulnerability)', () => {
|
|
46
|
+
// "/" is 0x2f, should be 1 byte, not 2
|
|
47
|
+
const bytes = new Uint8Array([0xc0, 0xaf])
|
|
48
|
+
expect(() => validateUtf8Strict(bytes)).toThrow(/Invalid UTF-8 start byte/)
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
it('should reject overlong 2-byte encoding of valid character', () => {
|
|
52
|
+
// U+007F encoded as 2 bytes instead of 1
|
|
53
|
+
const bytes = new Uint8Array([0xc1, 0xbf])
|
|
54
|
+
expect(() => validateUtf8Strict(bytes)).toThrow(/Invalid UTF-8 start byte/)
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
it('should reject overlong 3-byte encoding', () => {
|
|
58
|
+
// U+007F encoded as 3 bytes instead of 1
|
|
59
|
+
const bytes = new Uint8Array([0xe0, 0x81, 0xbf])
|
|
60
|
+
expect(() => validateUtf8Strict(bytes)).toThrow(/Overlong UTF-8/)
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
it('should reject overlong 4-byte encoding', () => {
|
|
64
|
+
// U+00FF encoded as 4 bytes instead of 2
|
|
65
|
+
const bytes = new Uint8Array([0xf0, 0x80, 0x83, 0xbf])
|
|
66
|
+
expect(() => validateUtf8Strict(bytes)).toThrow(/Overlong UTF-8/)
|
|
67
|
+
})
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
describe('validateUtf8Strict - Surrogate Codepoints', () => {
|
|
71
|
+
it('should reject high surrogate U+D800', () => {
|
|
72
|
+
const bytes = new Uint8Array([0xed, 0xa0, 0x80])
|
|
73
|
+
expect(() => validateUtf8Strict(bytes)).toThrow(/surrogate/)
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
it('should reject low surrogate U+DFFF', () => {
|
|
77
|
+
const bytes = new Uint8Array([0xed, 0xbf, 0xbf])
|
|
78
|
+
expect(() => validateUtf8Strict(bytes)).toThrow(/surrogate/)
|
|
79
|
+
})
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
describe('validateUtf8Strict - Invalid Continuation Bytes', () => {
|
|
83
|
+
it('should reject invalid continuation byte in 2-byte sequence', () => {
|
|
84
|
+
const bytes = new Uint8Array([0xc2, 0x00]) // Second byte should be 0x80-0xBF
|
|
85
|
+
expect(() => validateUtf8Strict(bytes)).toThrow(/continuation byte/)
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
it('should reject invalid continuation byte in 3-byte sequence', () => {
|
|
89
|
+
const bytes = new Uint8Array([0xe0, 0xa0, 0x00])
|
|
90
|
+
expect(() => validateUtf8Strict(bytes)).toThrow(/continuation byte/)
|
|
91
|
+
})
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
describe('validateUtf8Strict - Incomplete Sequences', () => {
|
|
95
|
+
it('should reject incomplete 2-byte sequence', () => {
|
|
96
|
+
const bytes = new Uint8Array([0xc2])
|
|
97
|
+
expect(() => validateUtf8Strict(bytes)).toThrow(/Incomplete UTF-8/)
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
it('should reject incomplete 3-byte sequence', () => {
|
|
101
|
+
const bytes = new Uint8Array([0xe0, 0xa0])
|
|
102
|
+
expect(() => validateUtf8Strict(bytes)).toThrow(/Incomplete UTF-8/)
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
it('should reject incomplete 4-byte sequence', () => {
|
|
106
|
+
const bytes = new Uint8Array([0xf0, 0x90, 0x80])
|
|
107
|
+
expect(() => validateUtf8Strict(bytes)).toThrow(/Incomplete UTF-8/)
|
|
108
|
+
})
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
describe('validateUtf8Strict - Codepoint Range', () => {
|
|
112
|
+
it('should reject codepoints beyond U+10FFFF', () => {
|
|
113
|
+
// Attempt to encode U+110000 (beyond max)
|
|
114
|
+
const bytes = new Uint8Array([0xf4, 0x90, 0x80, 0x80])
|
|
115
|
+
expect(() => validateUtf8Strict(bytes)).toThrow(/exceeds maximum/)
|
|
116
|
+
})
|
|
117
|
+
})
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
describe('Security: Canonical Integer Validation', () => {
|
|
121
|
+
describe('validateCanonicalInteger - Valid Canonical Forms', () => {
|
|
122
|
+
it('should accept value 10 with direct encoding (AI = 10)', () => {
|
|
123
|
+
expect(() => validateCanonicalInteger(10, 10)).not.toThrow()
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
it('should accept value 100 with 1-byte encoding (AI = 24)', () => {
|
|
127
|
+
expect(() => validateCanonicalInteger(100, 24)).not.toThrow()
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
it('should accept value 1000 with 2-byte encoding (AI = 25)', () => {
|
|
131
|
+
expect(() => validateCanonicalInteger(1000, 25)).not.toThrow()
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
it('should accept value 1000000 with 4-byte encoding (AI = 26)', () => {
|
|
135
|
+
expect(() => validateCanonicalInteger(1000000, 26)).not.toThrow()
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
it('should accept value > 4294967295 with 8-byte encoding (AI = 27)', () => {
|
|
139
|
+
expect(() => validateCanonicalInteger(10000000000n, 27)).not.toThrow()
|
|
140
|
+
})
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
describe('validateCanonicalInteger - Non-Canonical Forms', () => {
|
|
144
|
+
it('should reject value 10 encoded with AI = 24 (should be direct)', () => {
|
|
145
|
+
expect(() => validateCanonicalInteger(10, 24)).toThrow(/Non-canonical integer/)
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
it('should reject value 100 encoded with AI = 25 (should be 1-byte)', () => {
|
|
149
|
+
expect(() => validateCanonicalInteger(100, 25)).toThrow(/Non-canonical integer/)
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
it('should reject value 1000 encoded with AI = 26 (should be 2-byte)', () => {
|
|
153
|
+
expect(() => validateCanonicalInteger(1000, 26)).toThrow(/Non-canonical integer/)
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
it('should reject value 100000 encoded with AI = 27 (should be 4-byte)', () => {
|
|
157
|
+
expect(() => validateCanonicalInteger(100000, 27)).toThrow(/Non-canonical integer/)
|
|
158
|
+
})
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
describe('validateCanonicalInteger - Edge Cases', () => {
|
|
162
|
+
it('should validate value 0 with AI = 0', () => {
|
|
163
|
+
expect(() => validateCanonicalInteger(0, 0)).not.toThrow()
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
it('should validate value 23 with AI = 23 (max direct)', () => {
|
|
167
|
+
expect(() => validateCanonicalInteger(23, 23)).not.toThrow()
|
|
168
|
+
})
|
|
169
|
+
|
|
170
|
+
it('should validate value 24 with AI = 24 (min 1-byte)', () => {
|
|
171
|
+
expect(() => validateCanonicalInteger(24, 24)).not.toThrow()
|
|
172
|
+
})
|
|
173
|
+
|
|
174
|
+
it('should validate value 255 with AI = 24 (max 1-byte)', () => {
|
|
175
|
+
expect(() => validateCanonicalInteger(255, 24)).not.toThrow()
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
it('should validate value 256 with AI = 25 (min 2-byte)', () => {
|
|
179
|
+
expect(() => validateCanonicalInteger(256, 25)).not.toThrow()
|
|
180
|
+
})
|
|
181
|
+
|
|
182
|
+
it('should validate value 65535 with AI = 25 (max 2-byte)', () => {
|
|
183
|
+
expect(() => validateCanonicalInteger(65535, 25)).not.toThrow()
|
|
184
|
+
})
|
|
185
|
+
|
|
186
|
+
it('should validate value 65536 with AI = 26 (min 4-byte)', () => {
|
|
187
|
+
expect(() => validateCanonicalInteger(65536, 26)).not.toThrow()
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
it('should validate value 4294967295 with AI = 26 (max 4-byte)', () => {
|
|
191
|
+
expect(() => validateCanonicalInteger(4294967295, 26)).not.toThrow()
|
|
192
|
+
})
|
|
193
|
+
|
|
194
|
+
it('should validate value 4294967296 with AI = 27 (min 8-byte)', () => {
|
|
195
|
+
expect(() => validateCanonicalInteger(4294967296n, 27)).not.toThrow()
|
|
196
|
+
})
|
|
197
|
+
})
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
describe('Security: Byte Array Comparison', () => {
|
|
201
|
+
describe('compareBytes - Length Comparison', () => {
|
|
202
|
+
it('should return negative when first array is shorter', () => {
|
|
203
|
+
const a = new Uint8Array([0x01])
|
|
204
|
+
const b = new Uint8Array([0x01, 0x02])
|
|
205
|
+
expect(compareBytes(a, b)).toBeLessThan(0)
|
|
206
|
+
})
|
|
207
|
+
|
|
208
|
+
it('should return positive when first array is longer', () => {
|
|
209
|
+
const a = new Uint8Array([0x01, 0x02])
|
|
210
|
+
const b = new Uint8Array([0x01])
|
|
211
|
+
expect(compareBytes(a, b)).toBeGreaterThan(0)
|
|
212
|
+
})
|
|
213
|
+
})
|
|
214
|
+
|
|
215
|
+
describe('compareBytes - Lexicographic Comparison', () => {
|
|
216
|
+
it('should return 0 for identical arrays', () => {
|
|
217
|
+
const a = new Uint8Array([0x01, 0x02, 0x03])
|
|
218
|
+
const b = new Uint8Array([0x01, 0x02, 0x03])
|
|
219
|
+
expect(compareBytes(a, b)).toBe(0)
|
|
220
|
+
})
|
|
221
|
+
|
|
222
|
+
it('should return negative when first differs with lower byte', () => {
|
|
223
|
+
const a = new Uint8Array([0x01, 0x02, 0x03])
|
|
224
|
+
const b = new Uint8Array([0x01, 0x02, 0x04])
|
|
225
|
+
expect(compareBytes(a, b)).toBeLessThan(0)
|
|
226
|
+
})
|
|
227
|
+
|
|
228
|
+
it('should return positive when first differs with higher byte', () => {
|
|
229
|
+
const a = new Uint8Array([0x01, 0x02, 0x04])
|
|
230
|
+
const b = new Uint8Array([0x01, 0x02, 0x03])
|
|
231
|
+
expect(compareBytes(a, b)).toBeGreaterThan(0)
|
|
232
|
+
})
|
|
233
|
+
})
|
|
234
|
+
|
|
235
|
+
describe('compareBytes - Edge Cases', () => {
|
|
236
|
+
it('should handle empty arrays', () => {
|
|
237
|
+
const a = new Uint8Array([])
|
|
238
|
+
const b = new Uint8Array([])
|
|
239
|
+
expect(compareBytes(a, b)).toBe(0)
|
|
240
|
+
})
|
|
241
|
+
|
|
242
|
+
it('should handle empty vs non-empty', () => {
|
|
243
|
+
const a = new Uint8Array([])
|
|
244
|
+
const b = new Uint8Array([0x01])
|
|
245
|
+
expect(compareBytes(a, b)).toBeLessThan(0)
|
|
246
|
+
})
|
|
247
|
+
})
|
|
248
|
+
})
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utils Error Handling Tests
|
|
3
|
+
* Tests all error cases in utility functions for 100% code coverage
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, it, expect } from 'vitest'
|
|
7
|
+
import { readByte, readUint, readBigUint, hexToBytes } from '../utils'
|
|
8
|
+
|
|
9
|
+
describe('Utils - Error Handling', () => {
|
|
10
|
+
describe('readUint - Invalid Length', () => {
|
|
11
|
+
it('should throw error for length < 1', () => {
|
|
12
|
+
const buffer = new Uint8Array([1, 2, 3, 4])
|
|
13
|
+
expect(() => readUint(buffer, 0, 0)).toThrow('Invalid length: 0 (must be 1-8)')
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
it('should throw error for length > 8', () => {
|
|
17
|
+
const buffer = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
|
|
18
|
+
expect(() => readUint(buffer, 0, 9)).toThrow('Invalid length: 9 (must be 1-8)')
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
it('should throw error for negative length', () => {
|
|
22
|
+
const buffer = new Uint8Array([1, 2, 3, 4])
|
|
23
|
+
expect(() => readUint(buffer, 0, -1)).toThrow('Invalid length: -1 (must be 1-8)')
|
|
24
|
+
})
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
describe('readBigUint - Invalid Length', () => {
|
|
28
|
+
it('should throw error for length < 1', () => {
|
|
29
|
+
const buffer = new Uint8Array([1, 2, 3, 4])
|
|
30
|
+
expect(() => readBigUint(buffer, 0, 0)).toThrow('Invalid length: 0 (must be 1-8)')
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
it('should throw error for length > 8', () => {
|
|
34
|
+
const buffer = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
|
|
35
|
+
expect(() => readBigUint(buffer, 0, 9)).toThrow('Invalid length: 9 (must be 1-8)')
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
it('should throw error for negative length', () => {
|
|
39
|
+
const buffer = new Uint8Array([1, 2, 3, 4])
|
|
40
|
+
expect(() => readBigUint(buffer, 0, -1)).toThrow('Invalid length: -1 (must be 1-8)')
|
|
41
|
+
})
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
describe('readUint - Valid Lengths', () => {
|
|
45
|
+
it('should read 1-8 bytes successfully', () => {
|
|
46
|
+
const buffer = new Uint8Array([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08])
|
|
47
|
+
|
|
48
|
+
// Test all valid lengths (1-8)
|
|
49
|
+
expect(readUint(buffer, 0, 1)).toBe(0x01)
|
|
50
|
+
expect(readUint(buffer, 0, 2)).toBe(0x0102)
|
|
51
|
+
expect(readUint(buffer, 0, 3)).toBe(0x010203)
|
|
52
|
+
expect(readUint(buffer, 0, 4)).toBe(0x01020304)
|
|
53
|
+
expect(readUint(buffer, 0, 5)).toBe(0x0102030405)
|
|
54
|
+
expect(readUint(buffer, 0, 6)).toBe(0x010203040506)
|
|
55
|
+
expect(readUint(buffer, 0, 7)).toBe(0x01020304050607)
|
|
56
|
+
expect(readUint(buffer, 0, 8)).toBe(0x0102030405060708)
|
|
57
|
+
})
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
describe('readBigUint - Valid Lengths', () => {
|
|
61
|
+
it('should read 1-8 bytes successfully as BigInt', () => {
|
|
62
|
+
const buffer = new Uint8Array([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08])
|
|
63
|
+
|
|
64
|
+
// Test all valid lengths (1-8)
|
|
65
|
+
expect(readBigUint(buffer, 0, 1)).toBe(0x01n)
|
|
66
|
+
expect(readBigUint(buffer, 0, 2)).toBe(0x0102n)
|
|
67
|
+
expect(readBigUint(buffer, 0, 3)).toBe(0x010203n)
|
|
68
|
+
expect(readBigUint(buffer, 0, 4)).toBe(0x01020304n)
|
|
69
|
+
expect(readBigUint(buffer, 0, 5)).toBe(0x0102030405n)
|
|
70
|
+
expect(readBigUint(buffer, 0, 6)).toBe(0x010203040506n)
|
|
71
|
+
expect(readBigUint(buffer, 0, 7)).toBe(0x01020304050607n)
|
|
72
|
+
expect(readBigUint(buffer, 0, 8)).toBe(0x0102030405060708n)
|
|
73
|
+
})
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
describe('readByte - Out of Bounds', () => {
|
|
77
|
+
it('should throw error when reading beyond buffer', () => {
|
|
78
|
+
const buffer = new Uint8Array([1, 2, 3])
|
|
79
|
+
expect(() => readByte(buffer, 3)).toThrow('Offset 3 is out of bounds')
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
it('should not throw for negative offset (returns undefined, not an error in JS)', () => {
|
|
83
|
+
const buffer = new Uint8Array([1, 2, 3])
|
|
84
|
+
// Note: JavaScript Uint8Array with negative index returns undefined, not an error
|
|
85
|
+
// The check `offset >= buffer.length` doesn't catch negative numbers
|
|
86
|
+
// This is a known limitation but unlikely to occur in practice since CBOR parsing
|
|
87
|
+
// always uses non-negative offsets
|
|
88
|
+
expect(buffer[-1]).toBeUndefined()
|
|
89
|
+
})
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
describe('readUint - Out of Bounds', () => {
|
|
93
|
+
it('should throw error when reading beyond buffer', () => {
|
|
94
|
+
const buffer = new Uint8Array([1, 2, 3])
|
|
95
|
+
expect(() => readUint(buffer, 2, 2)).toThrow('Cannot read 2 bytes at offset 2')
|
|
96
|
+
})
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
describe('readBigUint - Out of Bounds', () => {
|
|
100
|
+
it('should throw error when reading beyond buffer', () => {
|
|
101
|
+
const buffer = new Uint8Array([1, 2, 3])
|
|
102
|
+
expect(() => readBigUint(buffer, 2, 2)).toThrow('Cannot read 2 bytes at offset 2')
|
|
103
|
+
})
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
describe('hexToBytes - Edge Cases', () => {
|
|
107
|
+
it('should return empty array for empty string', () => {
|
|
108
|
+
const result = hexToBytes('')
|
|
109
|
+
expect(result).toEqual(new Uint8Array(0))
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
it('should handle lowercase hex', () => {
|
|
113
|
+
const result = hexToBytes('abcd')
|
|
114
|
+
expect(result).toEqual(new Uint8Array([0xab, 0xcd]))
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
it('should handle uppercase hex', () => {
|
|
118
|
+
const result = hexToBytes('ABCD')
|
|
119
|
+
expect(result).toEqual(new Uint8Array([0xAB, 0xCD]))
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
it('should handle mixed case hex', () => {
|
|
123
|
+
const result = hexToBytes('AbCd')
|
|
124
|
+
expect(result).toEqual(new Uint8Array([0xab, 0xcd]))
|
|
125
|
+
})
|
|
126
|
+
})
|
|
127
|
+
})
|