Skip to content

Commit 58bfbfa

Browse files
author
Ant Skelton
committed
Fix bug with consecutive unbounded binary() parses
1 parent 9ca27ea commit 58bfbfa

2 files changed

Lines changed: 41 additions & 16 deletions

File tree

src/types/binary.js

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,43 +25,46 @@ function binary(name,
2525
reverseTransform = value => value,
2626
} = {}
2727
) {
28+
let instanceSize = size;
29+
2830
function parse(buffer, parseTree, { bigEndian }) {
2931
let offset = 0;
32+
instanceSize = size;
3033

3134
// determine size to copy to result buffer
3235
if (sizePrefixed) {
3336
const { parse: prefixParser } = uint('prefix', { size: sizePrefixLength, bigEndian: sizePrefixBigEndian });
3437
const result = prefixParser(buffer, {}, { bigEndian });
3538

36-
size = result.value;
39+
instanceSize = result.value;
3740
offset = result.size;
3841
}
3942
if (sizeField) {
40-
size = sizeFieldTransform(parseTree[sizeField]);
43+
instanceSize = sizeFieldTransform(parseTree[sizeField]);
4144
}
42-
if (size === undefined) {
43-
size = buffer.length;
45+
if (instanceSize === undefined) {
46+
instanceSize = buffer.length;
4447
}
4548

4649
// just copy data to result
47-
const result = new Buffer(size);
50+
const result = new Buffer(instanceSize);
4851

49-
buffer.copy(result, 0, offset, size + offset);
52+
buffer.copy(result, 0, offset, instanceSize + offset);
5053

5154
// return result
5255
return {
5356
value: transform(result),
54-
size: size + offset,
57+
size: instanceSize + offset,
5558
};
5659
}
5760

5861
function prepareEncode(object, parseTree, { bigEndian }) {
5962
if (size === undefined) {
60-
size = object.length;
63+
instanceSize = object.length;
6164
}
6265

6366
if (sizeField) {
64-
parseTree[sizeField] = sizeFieldReverseTransform(size);
67+
parseTree[sizeField] = sizeFieldReverseTransform(instanceSize);
6568
}
6669
}
6770

@@ -74,21 +77,21 @@ function binary(name,
7477
const result = prefixEncoder(transformed.length, { bigEndian });
7578

7679
bufferItems.unshift(result);
77-
size = transformed.length + sizePrefixLength;
80+
instanceSize = transformed.length + sizePrefixLength;
7881
}
79-
if (size === undefined) {
80-
size = transformed.length;
82+
if (instanceSize === undefined) {
83+
instanceSize = transformed.length;
8184
}
8285

8386
// build buffer
8487
let data = Buffer.concat(bufferItems);
8588

86-
if (data.length < size) {
89+
if (data.length < instanceSize) {
8790
// if the buffer was shorter than anticipated, pad with zeroes
88-
data = Buffer.concat([data, Buffer.alloc(size - data.length)]);
89-
} else if (data.length > size) {
91+
data = Buffer.concat([data, Buffer.alloc(instanceSize - data.length)]);
92+
} else if (data.length > instanceSize) {
9093
// if the buffer was longer just cut it off
91-
data = data.slice(0, size);
94+
data = data.slice(0, instanceSize);
9295
}
9396

9497
return data;

test/binary.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,25 @@ test('bcd_4byte', (t) => {
7474

7575
t.is(compareTemplate(template(definition), { bcd: null }), true);
7676
});
77+
78+
test("binary_reuse_with_undefined_size", (t) => {
79+
const definition = [binary("bin")];
80+
const buffer = Buffer.from("0d0a", "hex");
81+
const buffer2 = Buffer.from("0a0b0c0d", "hex");
82+
const parsed = parse(definition, buffer);
83+
const parsed2 = parse(definition, buffer2);
84+
const encoded = encode(definition, parsed);
85+
const encoded2 = encode(definition, parsed2);
86+
87+
t.is(parsed.bin.length, 2);
88+
t.is(parsed.bin[0], 0x0d);
89+
t.is(parsed.bin[1], 0x0a);
90+
t.is(encoded.compare(buffer), 0);
91+
92+
t.is(parsed2.bin.length, 4);
93+
t.is(parsed2.bin[0], 0x0a);
94+
t.is(parsed2.bin[1], 0x0b);
95+
t.is(parsed2.bin[2], 0x0c);
96+
t.is(parsed2.bin[3], 0x0d);
97+
t.is(encoded2.compare(buffer2), 0);
98+
});

0 commit comments

Comments
 (0)