cbor-x 1.6.8 → 1.6.9
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/README.md +4 -0
- package/decode.js +151 -28
- package/dist/decode-no-eval.cjs +152 -28
- package/dist/decode-no-eval.cjs.map +1 -1
- package/dist/index-no-eval.cjs +540 -48
- package/dist/index-no-eval.cjs.map +1 -1
- package/dist/index-no-eval.min.js +1 -1
- package/dist/index-no-eval.min.js.map +1 -1
- package/dist/index.js +540 -48
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/node.cjs +595 -100
- package/dist/node.cjs.map +1 -1
- package/dist/test.js +147 -30
- package/dist/test.js.map +1 -1
- package/encode.js +21 -2
- package/index.d.ts +1 -1
- package/iterators.js +123 -19
- package/package.json +2 -2
- package/scan.js +253 -0
- package/stream.js +9 -10
package/dist/test.js
CHANGED
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
const RECORD_INLINE_ID = 0xdfff; // temporary first-come first-serve tag // proposed tag: 0x7265 // 're'
|
|
16
16
|
const BUNDLED_STRINGS_ID = 0xdff9;
|
|
17
17
|
const PACKED_REFERENCE_TAG_ID = 6;
|
|
18
|
-
const STOP_CODE = {};
|
|
19
18
|
let maxArraySize = 112810000; // This is the maximum array size in V8. We would potentially detect and set it higher
|
|
20
19
|
// for JSC, but this is pretty large and should be sufficient for most use cases
|
|
21
20
|
let maxMapSize = 16810000; // JavaScript has a fixed maximum map size of about 16710000, but JS itself enforces this,
|
|
@@ -126,16 +125,11 @@
|
|
|
126
125
|
// re-entrant execution, save the state and restore it after we do this decode
|
|
127
126
|
return saveState(() => {
|
|
128
127
|
clearSource();
|
|
129
|
-
|
|
130
|
-
return this ? this.decode(source, end) : Decoder.prototype.decode.call(defaultOptions, source, end)
|
|
131
|
-
} catch (error) {
|
|
132
|
-
if (error && typeof error == 'object')
|
|
133
|
-
nestedDecodeErrors.add(error);
|
|
134
|
-
throw error
|
|
135
|
-
}
|
|
128
|
+
return this ? this.decode(source, end) : Decoder.prototype.decode.call(defaultOptions, source, end)
|
|
136
129
|
})
|
|
137
130
|
}
|
|
138
|
-
|
|
131
|
+
// past the view, the JS string readers would decode the missing bytes as zeros instead of failing as truncated
|
|
132
|
+
srcEnd = end > -1 && end < source.length ? end : source.length;
|
|
139
133
|
position$1 = 0;
|
|
140
134
|
stringPosition = 0;
|
|
141
135
|
srcStringEnd = 0;
|
|
@@ -175,18 +169,28 @@
|
|
|
175
169
|
return checkedRead()
|
|
176
170
|
}
|
|
177
171
|
decodeMultiple(source, forEach) {
|
|
172
|
+
if (src) {
|
|
173
|
+
// Keep the complete nested sequence inside its own decoder state.
|
|
174
|
+
return saveState(() => {
|
|
175
|
+
clearSource();
|
|
176
|
+
return this ? this.decodeMultiple(source, forEach) : defaultDecoder.decodeMultiple(source, forEach)
|
|
177
|
+
})
|
|
178
|
+
}
|
|
178
179
|
let values, lastPosition = 0;
|
|
179
180
|
try {
|
|
180
181
|
let size = source.length;
|
|
181
182
|
sequentialMode = true;
|
|
182
183
|
let value = this ? this.decode(source, size) : defaultDecoder.decode(source, size);
|
|
183
184
|
if (forEach) {
|
|
185
|
+
let end = position$1;
|
|
184
186
|
if (forEach(value) === false) {
|
|
185
187
|
return
|
|
186
188
|
}
|
|
187
|
-
while(
|
|
188
|
-
lastPosition =
|
|
189
|
-
|
|
189
|
+
while(end < size) {
|
|
190
|
+
lastPosition = end;
|
|
191
|
+
value = checkedRead();
|
|
192
|
+
end = position$1;
|
|
193
|
+
if (forEach(value) === false) {
|
|
190
194
|
return
|
|
191
195
|
}
|
|
192
196
|
}
|
|
@@ -200,8 +204,10 @@
|
|
|
200
204
|
return values
|
|
201
205
|
}
|
|
202
206
|
} catch(error) {
|
|
203
|
-
error
|
|
204
|
-
|
|
207
|
+
if (error && (typeof error == 'object' || typeof error == 'function')) {
|
|
208
|
+
error.lastPosition = lastPosition;
|
|
209
|
+
error.values = values;
|
|
210
|
+
}
|
|
205
211
|
throw error
|
|
206
212
|
} finally {
|
|
207
213
|
sequentialMode = false;
|
|
@@ -255,9 +261,21 @@
|
|
|
255
261
|
}
|
|
256
262
|
}
|
|
257
263
|
|
|
258
|
-
function
|
|
264
|
+
function readBreak() {
|
|
265
|
+
if (position$1 < srcEnd && src[position$1] === 0xff) {
|
|
266
|
+
position$1++;
|
|
267
|
+
return true
|
|
268
|
+
}
|
|
269
|
+
return false
|
|
270
|
+
}
|
|
271
|
+
// neededEnd, from a length check, is a position that the source must extend to before the item can decode. It is a
|
|
272
|
+
// lower bound for any completion of the source: every byte read before the check was within the source, so a longer
|
|
273
|
+
// source reaches the same check with the same length. Streams wait for it instead of decoding on every chunk.
|
|
274
|
+
function endOfCBORError(neededEnd) {
|
|
259
275
|
let error = new Error('Unexpected end of CBOR data');
|
|
260
276
|
error.incomplete = true;
|
|
277
|
+
if (neededEnd)
|
|
278
|
+
error.neededEnd = neededEnd;
|
|
261
279
|
return error
|
|
262
280
|
}
|
|
263
281
|
|
|
@@ -309,6 +327,9 @@
|
|
|
309
327
|
} else if (currentDecoder.int64AsNumber) {
|
|
310
328
|
token = dataView.getUint32(position$1) * 0x100000000;
|
|
311
329
|
token += dataView.getUint32(position$1 + 4);
|
|
330
|
+
position$1 += 8;
|
|
331
|
+
if (majorType === 1) return -1 - token
|
|
332
|
+
break
|
|
312
333
|
} else token = dataView.getBigUint64(position$1);
|
|
313
334
|
position$1 += 8;
|
|
314
335
|
break
|
|
@@ -320,10 +341,10 @@
|
|
|
320
341
|
throw new Error('Indefinite length not supported for byte or text strings')
|
|
321
342
|
case 4: // array
|
|
322
343
|
let array = [];
|
|
323
|
-
let
|
|
324
|
-
while ((
|
|
344
|
+
let i = 0;
|
|
345
|
+
while (!readBreak()) {
|
|
325
346
|
if (i >= maxArraySize) throw new Error(`Array length exceeds ${maxArraySize}`)
|
|
326
|
-
array[i++] =
|
|
347
|
+
array[i++] = read();
|
|
327
348
|
}
|
|
328
349
|
return majorType == 4 ? array : majorType == 3 ? array.join('') : Buffer.concat(array)
|
|
329
350
|
case 5: // map
|
|
@@ -332,13 +353,15 @@
|
|
|
332
353
|
let object = {};
|
|
333
354
|
let i = 0;
|
|
334
355
|
if (currentDecoder.keyMap) {
|
|
335
|
-
while((
|
|
356
|
+
while (!readBreak()) {
|
|
357
|
+
key = read();
|
|
336
358
|
if (i++ >= objectSizeLimit) throw new Error(`Property count exceeds ${objectSizeLimit}`)
|
|
337
359
|
object[safeKey(currentDecoder.decodeKey(key))] = read();
|
|
338
360
|
}
|
|
339
361
|
}
|
|
340
362
|
else {
|
|
341
|
-
while ((
|
|
363
|
+
while (!readBreak()) {
|
|
364
|
+
key = read();
|
|
342
365
|
if (i++ >= objectSizeLimit) throw new Error(`Property count exceeds ${objectSizeLimit}`)
|
|
343
366
|
object[safeKey(key)] = read();
|
|
344
367
|
}
|
|
@@ -352,7 +375,8 @@
|
|
|
352
375
|
let map = new Map();
|
|
353
376
|
if (currentDecoder.keyMap) {
|
|
354
377
|
let i = 0;
|
|
355
|
-
while((
|
|
378
|
+
while (!readBreak()) {
|
|
379
|
+
key = read();
|
|
356
380
|
if (i++ >= maxMapSize) {
|
|
357
381
|
throw new Error(`Map size exceeds ${maxMapSize}`);
|
|
358
382
|
}
|
|
@@ -361,7 +385,8 @@
|
|
|
361
385
|
}
|
|
362
386
|
else {
|
|
363
387
|
let i = 0;
|
|
364
|
-
while ((
|
|
388
|
+
while (!readBreak()) {
|
|
389
|
+
key = read();
|
|
365
390
|
if (i++ >= maxMapSize) {
|
|
366
391
|
throw new Error(`Map size exceeds ${maxMapSize}`);
|
|
367
392
|
}
|
|
@@ -371,7 +396,8 @@
|
|
|
371
396
|
return map
|
|
372
397
|
}
|
|
373
398
|
case 7:
|
|
374
|
-
|
|
399
|
+
// readBreak consumes every break that ends an indefinite-length item
|
|
400
|
+
throw new Error('Unexpected break stop code outside of an indefinite-length item')
|
|
375
401
|
default:
|
|
376
402
|
throw new Error('Invalid major type for indefinite length ' + majorType)
|
|
377
403
|
}
|
|
@@ -385,13 +411,13 @@
|
|
|
385
411
|
case 1: // negative int
|
|
386
412
|
return ~token
|
|
387
413
|
case 2: // buffer
|
|
388
|
-
if (token > srcEnd - position$1) throw endOfCBORError()
|
|
414
|
+
if (token > srcEnd - position$1) throw endOfCBORError(position$1 + token)
|
|
389
415
|
return readBin(token)
|
|
390
416
|
case 3: // string
|
|
391
417
|
if (srcStringEnd >= position$1) { // already extracted, which only covers complete strings
|
|
392
418
|
return srcString.slice(position$1 - srcStringStart, (position$1 += token) - srcStringStart)
|
|
393
419
|
}
|
|
394
|
-
if (token > srcEnd - position$1) throw endOfCBORError()
|
|
420
|
+
if (token > srcEnd - position$1) throw endOfCBORError(position$1 + token)
|
|
395
421
|
if (srcStringEnd == 0 && srcEnd < 140 && token < 32) {
|
|
396
422
|
// for small blocks, avoiding the overhead of the extract call is helpful
|
|
397
423
|
let string = token < 16 ? shortStringInJS(token) : longStringInJS(token);
|
|
@@ -405,7 +431,7 @@
|
|
|
405
431
|
// never be satisfied; check before allocating so a tiny header can not force a huge allocation
|
|
406
432
|
// nested arrays each pass the check above yet still preallocate, so also spend from a
|
|
407
433
|
// per-decode budget of the remaining bytes; the summed lengths of any valid tree stay under it
|
|
408
|
-
if (token > srcEnd - position$1 || (arrayAllocationBudget -= token) < 0) throw endOfCBORError()
|
|
434
|
+
if (token > srcEnd - position$1 || (arrayAllocationBudget -= token) < 0) throw endOfCBORError(position$1 + token)
|
|
409
435
|
let array = new Array(token);
|
|
410
436
|
//if (currentDecoder.keyMap) for (let i = 0; i < token; i++) array[i] = currentDecoder.decodeKey(read())
|
|
411
437
|
//else
|
|
@@ -414,7 +440,7 @@
|
|
|
414
440
|
case 5: // map
|
|
415
441
|
if (currentDecoder.mapsAsObjects) {
|
|
416
442
|
if (token > objectSizeLimit) throw new Error(`Property count exceeds ${objectSizeLimit}`)
|
|
417
|
-
if (token > (srcEnd - position$1) / 2) throw endOfCBORError() // each entry needs at least two bytes
|
|
443
|
+
if (token > (srcEnd - position$1) / 2) throw endOfCBORError(position$1 + 2 * token) // each entry needs at least two bytes
|
|
418
444
|
let object = {};
|
|
419
445
|
if (currentDecoder.keyMap) for (let i = 0; i < token; i++) object[safeKey(currentDecoder.decodeKey(read()))] = read();
|
|
420
446
|
else for (let i = 0; i < token; i++) object[safeKey(read())] = read();
|
|
@@ -425,7 +451,7 @@
|
|
|
425
451
|
restoreMapsAsObject = false;
|
|
426
452
|
}
|
|
427
453
|
if (token > maxMapSize) throw new Error(`Map size exceeds ${maxMapSize}`)
|
|
428
|
-
if (token > (srcEnd - position$1) / 2) throw endOfCBORError()
|
|
454
|
+
if (token > (srcEnd - position$1) / 2) throw endOfCBORError(position$1 + 2 * token)
|
|
429
455
|
let map = new Map();
|
|
430
456
|
if (currentDecoder.keyMap) for (let i = 0; i < token; i++) map.set(currentDecoder.decodeKey(read()),read());
|
|
431
457
|
else for (let i = 0; i < token; i++) map.set(read(), read());
|
|
@@ -938,6 +964,7 @@
|
|
|
938
964
|
}
|
|
939
965
|
return object
|
|
940
966
|
};
|
|
967
|
+
const legacyRecordDefinition = currentExtensions[LEGACY_RECORD_INLINE_ID];
|
|
941
968
|
currentExtensions[14] = (value) => {
|
|
942
969
|
if (bundledStrings$1)
|
|
943
970
|
return bundledStrings$1[0].slice(bundledStrings$1.position0, bundledStrings$1.position0 += value)
|
|
@@ -1210,6 +1237,8 @@
|
|
|
1210
1237
|
}
|
|
1211
1238
|
|
|
1212
1239
|
function saveState(callback) {
|
|
1240
|
+
let savedFragmentReader = fragmentReadString;
|
|
1241
|
+
let savedReadFixedString = readFixedString;
|
|
1213
1242
|
let savedSrcEnd = srcEnd;
|
|
1214
1243
|
let savedPosition = position$1;
|
|
1215
1244
|
let savedStringPosition = stringPosition;
|
|
@@ -1219,6 +1248,7 @@
|
|
|
1219
1248
|
let savedStrings = strings;
|
|
1220
1249
|
let savedReferenceMap = referenceMap;
|
|
1221
1250
|
let savedBundledStrings = bundledStrings$1;
|
|
1251
|
+
let savedPackedValues = packedValues;
|
|
1222
1252
|
|
|
1223
1253
|
// TODO: We may need to revisit this if we do more external calls to user code (since it could be slow)
|
|
1224
1254
|
let savedSrc = new Uint8Array(src.slice(0, srcEnd)); // we copy the data in case it changes while external data is processed
|
|
@@ -1227,10 +1257,20 @@
|
|
|
1227
1257
|
let savedSequentialMode = sequentialMode;
|
|
1228
1258
|
let savedRestoreMapsAsObject = restoreMapsAsObject;
|
|
1229
1259
|
let savedArrayAllocationBudget = arrayAllocationBudget;
|
|
1260
|
+
if (fragmentReadString) readFixedString = fragmentReadString;
|
|
1261
|
+
fragmentReadString = null;
|
|
1230
1262
|
restoreMapsAsObject = false;
|
|
1231
1263
|
try {
|
|
1232
1264
|
return callback()
|
|
1265
|
+
} catch (error) {
|
|
1266
|
+
// the callback decodes its own source (a shared structures blob, or an extension's embedded data), so a
|
|
1267
|
+
// truncation there cannot be completed by more of the outer input; checkedRead() clears the flag
|
|
1268
|
+
if (error && (typeof error == 'object' || typeof error == 'function'))
|
|
1269
|
+
nestedDecodeErrors.add(error);
|
|
1270
|
+
throw error
|
|
1233
1271
|
} finally {
|
|
1272
|
+
fragmentReadString = savedFragmentReader;
|
|
1273
|
+
readFixedString = savedReadFixedString;
|
|
1234
1274
|
srcEnd = savedSrcEnd;
|
|
1235
1275
|
position$1 = savedPosition;
|
|
1236
1276
|
stringPosition = savedStringPosition;
|
|
@@ -1240,6 +1280,7 @@
|
|
|
1240
1280
|
strings = savedStrings;
|
|
1241
1281
|
referenceMap = savedReferenceMap;
|
|
1242
1282
|
bundledStrings$1 = savedBundledStrings;
|
|
1283
|
+
packedValues = savedPackedValues;
|
|
1243
1284
|
src = savedSrc;
|
|
1244
1285
|
sequentialMode = savedSequentialMode;
|
|
1245
1286
|
currentStructures = savedStructures;
|
|
@@ -1255,8 +1296,15 @@
|
|
|
1255
1296
|
currentStructures = null;
|
|
1256
1297
|
}
|
|
1257
1298
|
|
|
1299
|
+
const registeredExtensions = new Map();
|
|
1300
|
+
let fragmentReadString;
|
|
1301
|
+
|
|
1302
|
+
new Map([[LEGACY_RECORD_INLINE_ID, legacyRecordDefinition], [259, currentExtensions[259]]]);
|
|
1303
|
+
|
|
1258
1304
|
function addExtension$2(extension) {
|
|
1259
1305
|
currentExtensions[extension.tag] = extension.decode;
|
|
1306
|
+
if (typeof extension.decode === 'function') registeredExtensions.set(extension.tag, extension.decode);
|
|
1307
|
+
else registeredExtensions.delete(extension.tag);
|
|
1260
1308
|
}
|
|
1261
1309
|
|
|
1262
1310
|
const mult10 = new Array(147); // this is a table matching binary exponents to the multiplier to determine significant digit rounding
|
|
@@ -1844,6 +1892,11 @@
|
|
|
1844
1892
|
return encode(json)
|
|
1845
1893
|
}
|
|
1846
1894
|
|
|
1895
|
+
// not in extensions, so class instances that reach writeObject do not pay another instanceof
|
|
1896
|
+
if (constructor === DataView) {
|
|
1897
|
+
writeBuffer(new Uint8Array(value.buffer, value.byteOffset, value.byteLength), makeRoom);
|
|
1898
|
+
return
|
|
1899
|
+
}
|
|
1847
1900
|
// no extension found, write as a plain object
|
|
1848
1901
|
writeObject(value);
|
|
1849
1902
|
}
|
|
@@ -1937,8 +1990,22 @@
|
|
|
1937
1990
|
size++;
|
|
1938
1991
|
}
|
|
1939
1992
|
}
|
|
1940
|
-
|
|
1941
|
-
|
|
1993
|
+
if (size < 0x10000) {
|
|
1994
|
+
// fits in a map-16 (uint16) count: back-patch the reserved 2 bytes
|
|
1995
|
+
target[objectOffset++ + start] = size >> 8;
|
|
1996
|
+
target[objectOffset + start] = size & 0xff;
|
|
1997
|
+
} else {
|
|
1998
|
+
// too many entries for a map-16 count: widen the already-written header
|
|
1999
|
+
// to map-32, mirroring writeArrayHeader's 0x9a/setUint32 path. Shift the
|
|
2000
|
+
// encoded entries 2 bytes forward to make room for the wider (uint32) count.
|
|
2001
|
+
if (position + 2 > safeEnd)
|
|
2002
|
+
makeRoom(position + 2);
|
|
2003
|
+
let headerPosition = objectOffset + start;
|
|
2004
|
+
target.copyWithin(headerPosition + 4, headerPosition + 2, position);
|
|
2005
|
+
position += 2;
|
|
2006
|
+
target[headerPosition - 1] = 0xba; // map 32
|
|
2007
|
+
targetView.setUint32(headerPosition, size);
|
|
2008
|
+
}
|
|
1942
2009
|
} :
|
|
1943
2010
|
(object, skipValues) => {
|
|
1944
2011
|
let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null));
|
|
@@ -2677,6 +2744,15 @@
|
|
|
2677
2744
|
assert.throws(() => decode$1(Buffer.from('7a10000000', 'hex')));
|
|
2678
2745
|
});
|
|
2679
2746
|
|
|
2747
|
+
test('break stop code outside indefinite-length item', function() {
|
|
2748
|
+
assert.throws(() => decode$1(Buffer.from('ff', 'hex')));
|
|
2749
|
+
assert.throws(() => decode$1(Buffer.from('81ff', 'hex')));
|
|
2750
|
+
assert.throws(() => decode$1(Buffer.from('a16161ff', 'hex')));
|
|
2751
|
+
assert.throws(() => decode$1(Buffer.from('c0ff', 'hex')));
|
|
2752
|
+
assert.deepEqual(decode$1(Buffer.from('9f01ff', 'hex')), [1]);
|
|
2753
|
+
assert.deepEqual(decode$1(Buffer.from('bf616101ff', 'hex')), { a: 1 });
|
|
2754
|
+
});
|
|
2755
|
+
|
|
2680
2756
|
test('overlong encoding', function() {
|
|
2681
2757
|
const payload = Buffer.from([0x62, 0xc0, 0xaf]);
|
|
2682
2758
|
const result = decode$1(payload);
|
|
@@ -3016,6 +3092,24 @@
|
|
|
3016
3092
|
var decoded = decode(encoded);
|
|
3017
3093
|
assert.equal(decoded.length, 0);
|
|
3018
3094
|
});
|
|
3095
|
+
test('fixed map size overflow (map-16 to map-32)', function() {
|
|
3096
|
+
this.timeout(120000);
|
|
3097
|
+
// issue #131: the default encode() serializes objects with a back-patched
|
|
3098
|
+
// map-16 (uint16) header, so an object with >= 65536 keys overflowed the
|
|
3099
|
+
// count and the decoder stopped early with "Data read, but end of buffer not
|
|
3100
|
+
// reached". Verify the round-trip across the map-16 -> map-32 boundary.
|
|
3101
|
+
function roundTripObjectWith(count) {
|
|
3102
|
+
var data = {};
|
|
3103
|
+
for (var i = 0; i < count; i++)
|
|
3104
|
+
data['k' + i] = i;
|
|
3105
|
+
var decoded = decode(encode(data));
|
|
3106
|
+
assert.equal(Object.keys(decoded).length, count);
|
|
3107
|
+
assert.deepEqual(decoded, data);
|
|
3108
|
+
}
|
|
3109
|
+
roundTripObjectWith(65535); // map-16 path, must stay unchanged
|
|
3110
|
+
roundTripObjectWith(65536); // first size that needs map-32
|
|
3111
|
+
roundTripObjectWith(70000); // well past the 16-bit boundary
|
|
3112
|
+
});
|
|
3019
3113
|
|
|
3020
3114
|
test('random strings', function(){
|
|
3021
3115
|
var data = [];
|
|
@@ -3142,6 +3236,14 @@
|
|
|
3142
3236
|
var deserialized = encoder.decode(serialized);
|
|
3143
3237
|
assert.equal(deserialized, data);
|
|
3144
3238
|
});
|
|
3239
|
+
test('negative int64 as number', function() {
|
|
3240
|
+
let encoded = Buffer.from('3b0000000e96848f5f', 'hex');
|
|
3241
|
+
assert.equal(new Decoder().decode(encoded), -62654812000n);
|
|
3242
|
+
|
|
3243
|
+
let decoder = new Decoder({ int64AsNumber: true });
|
|
3244
|
+
assert.equal(decoder.decode(encoded), -62654812000);
|
|
3245
|
+
assert.equal(decoder.decode(Buffer.from('3b001ffffffffffffe', 'hex')), Number.MIN_SAFE_INTEGER);
|
|
3246
|
+
});
|
|
3145
3247
|
test('bigint to float', function() {
|
|
3146
3248
|
var data = {
|
|
3147
3249
|
a: 325283295382932843n
|
|
@@ -3186,6 +3288,21 @@
|
|
|
3186
3288
|
assert.equal(decoded[2], 5);
|
|
3187
3289
|
assert.equal(decoded.byteLength, 3);
|
|
3188
3290
|
});
|
|
3291
|
+
test('encode DataView', function() {
|
|
3292
|
+
let bytes = new Uint8Array(40).map((_, i) => i);
|
|
3293
|
+
assert.equal(Buffer.from(encode(new DataView(bytes.buffer, 3, 4))).toString('hex'), '4403040506');
|
|
3294
|
+
assert.equal(Buffer.from(encode(new DataView(bytes.buffer, 5, 30))).toString('hex'),
|
|
3295
|
+
'581e' + Buffer.from(bytes.subarray(5, 35)).toString('hex'));
|
|
3296
|
+
assert.equal(Buffer.from(encode(new DataView(bytes.buffer, 0, 0))).toString('hex'), '40');
|
|
3297
|
+
assert.deepEqual(decode(encode({ v: new DataView(bytes.buffer, 1, 2) })), { v: Buffer.from([1, 2]) });
|
|
3298
|
+
assert.equal(Buffer.from(encode(bytes.buffer.slice(1, 4))).toString('hex'), '43010203');
|
|
3299
|
+
assert.equal(Buffer.from(encode(bytes.subarray(1, 4))).toString('hex'), 'd84043010203');
|
|
3300
|
+
assert.equal(Buffer.from(encode(Buffer.from(bytes.subarray(1, 4)))).toString('hex'), '43010203');
|
|
3301
|
+
assert.equal(Buffer.from(new Encoder({ tagUint8Array: false }).encode(bytes.subarray(1, 4))).toString('hex'), '43010203');
|
|
3302
|
+
let uint16Tag = new Uint8Array(new Uint16Array([1]).buffer)[0] == 1 ? '45' : '41';
|
|
3303
|
+
assert.equal(Buffer.from(encode(new Uint16Array(bytes.buffer, 2, 2))).toString('hex'), 'd8' + uint16Tag + '4402030405');
|
|
3304
|
+
assert.equal(Buffer.from(encode(new Uint8ClampedArray(bytes.buffer, 2, 2))).toString('hex'), 'd844420203');
|
|
3305
|
+
});
|
|
3189
3306
|
|
|
3190
3307
|
test('iterator/indefinite length array', function(){
|
|
3191
3308
|
class NotArray {
|