Skip to content

Commit 80d7f03

Browse files
authored
fix(NODE-3493): code and symbol tests are partially testing the wrong types (#459)
1 parent cc5d04d commit 80d7f03

File tree

3 files changed

+45
-37
lines changed

3 files changed

+45
-37
lines changed

src/parser/deserializer.ts

+25-17
Original file line numberDiff line numberDiff line change
@@ -173,20 +173,12 @@ function deserializeObject(
173173
stringSize <= 0 ||
174174
stringSize > buffer.length - index ||
175175
buffer[index + stringSize - 1] !== 0
176-
)
176+
) {
177177
throw new Error('bad string length in bson');
178-
179-
value = buffer.toString('utf8', index, index + stringSize - 1);
180-
181-
for (let i = 0; i < value.length; i++) {
182-
if (value.charCodeAt(i) === 0xfffd) {
183-
if (!validateUtf8(buffer, index, index + stringSize - 1)) {
184-
throw new Error('Invalid UTF-8 string in BSON document');
185-
}
186-
break;
187-
}
188178
}
189179

180+
value = getValidatedString(buffer, index, index + stringSize - 1);
181+
190182
index = index + stringSize;
191183
} else if (elementType === constants.BSON_DATA_OID) {
192184
const oid = Buffer.alloc(12);
@@ -464,9 +456,10 @@ function deserializeObject(
464456
stringSize <= 0 ||
465457
stringSize > buffer.length - index ||
466458
buffer[index + stringSize - 1] !== 0
467-
)
459+
) {
468460
throw new Error('bad string length in bson');
469-
const symbol = buffer.toString('utf8', index, index + stringSize - 1);
461+
}
462+
const symbol = getValidatedString(buffer, index, index + stringSize - 1);
470463
value = promoteValues ? symbol : new BSONSymbol(symbol);
471464
index = index + stringSize;
472465
} else if (elementType === constants.BSON_DATA_TIMESTAMP) {
@@ -496,9 +489,10 @@ function deserializeObject(
496489
stringSize <= 0 ||
497490
stringSize > buffer.length - index ||
498491
buffer[index + stringSize - 1] !== 0
499-
)
492+
) {
500493
throw new Error('bad string length in bson');
501-
const functionString = buffer.toString('utf8', index, index + stringSize - 1);
494+
}
495+
const functionString = getValidatedString(buffer, index, index + stringSize - 1);
502496

503497
// If we are evaluating the functions
504498
if (evalFunctions) {
@@ -538,11 +532,12 @@ function deserializeObject(
538532
stringSize <= 0 ||
539533
stringSize > buffer.length - index ||
540534
buffer[index + stringSize - 1] !== 0
541-
)
535+
) {
542536
throw new Error('bad string length in bson');
537+
}
543538

544539
// Javascript function
545-
const functionString = buffer.toString('utf8', index, index + stringSize - 1);
540+
const functionString = getValidatedString(buffer, index, index + stringSize - 1);
546541
// Update parse index position
547542
index = index + stringSize;
548543
// Parse the element
@@ -670,3 +665,16 @@ function isolateEval(
670665
// Set the object
671666
return functionCache[functionString].bind(object);
672667
}
668+
669+
function getValidatedString(buffer: Buffer, start: number, end: number) {
670+
const value = buffer.toString('utf8', start, end);
671+
for (let i = 0; i < value.length; i++) {
672+
if (value.charCodeAt(i) === 0xfffd) {
673+
if (!validateUtf8(buffer, start, end)) {
674+
throw new Error('Invalid UTF-8 string in BSON document');
675+
}
676+
break;
677+
}
678+
}
679+
return value;
680+
}

test/node/specs/bson-corpus/code.json

+13-13
Original file line numberDiff line numberDiff line change
@@ -20,48 +20,48 @@
2020
},
2121
{
2222
"description": "two-byte UTF-8 (\u00e9)",
23-
"canonical_bson": "190000000261000D000000C3A9C3A9C3A9C3A9C3A9C3A90000",
24-
"canonical_extjson": "{\"a\" : \"\\u00e9\\u00e9\\u00e9\\u00e9\\u00e9\\u00e9\"}"
23+
"canonical_bson": "190000000D61000D000000C3A9C3A9C3A9C3A9C3A9C3A90000",
24+
"canonical_extjson": "{\"a\" : {\"$code\" : \"\\u00e9\\u00e9\\u00e9\\u00e9\\u00e9\\u00e9\"}}"
2525
},
2626
{
2727
"description": "three-byte UTF-8 (\u2606)",
28-
"canonical_bson": "190000000261000D000000E29886E29886E29886E298860000",
29-
"canonical_extjson": "{\"a\" : \"\\u2606\\u2606\\u2606\\u2606\"}"
28+
"canonical_bson": "190000000D61000D000000E29886E29886E29886E298860000",
29+
"canonical_extjson": "{\"a\" : {\"$code\" : \"\\u2606\\u2606\\u2606\\u2606\"}}"
3030
},
3131
{
3232
"description": "Embedded nulls",
33-
"canonical_bson": "190000000261000D0000006162006261620062616261620000",
34-
"canonical_extjson": "{\"a\" : \"ab\\u0000bab\\u0000babab\"}"
33+
"canonical_bson": "190000000D61000D0000006162006261620062616261620000",
34+
"canonical_extjson": "{\"a\" : {\"$code\" : \"ab\\u0000bab\\u0000babab\"}}"
3535
}
3636
],
3737
"decodeErrors": [
3838
{
3939
"description": "bad code string length: 0 (but no 0x00 either)",
40-
"bson": "0C0000000261000000000000"
40+
"bson": "0C0000000D61000000000000"
4141
},
4242
{
4343
"description": "bad code string length: -1",
44-
"bson": "0C000000026100FFFFFFFF00"
44+
"bson": "0C0000000D6100FFFFFFFF00"
4545
},
4646
{
4747
"description": "bad code string length: eats terminator",
48-
"bson": "10000000026100050000006200620000"
48+
"bson": "100000000D6100050000006200620000"
4949
},
5050
{
5151
"description": "bad code string length: longer than rest of document",
52-
"bson": "120000000200FFFFFF00666F6F6261720000"
52+
"bson": "120000000D00FFFFFF00666F6F6261720000"
5353
},
5454
{
5555
"description": "code string is not null-terminated",
56-
"bson": "1000000002610004000000616263FF00"
56+
"bson": "100000000D610004000000616263FF00"
5757
},
5858
{
5959
"description": "empty code string, but extra null",
60-
"bson": "0E00000002610001000000000000"
60+
"bson": "0E0000000D610001000000000000"
6161
},
6262
{
6363
"description": "invalid UTF-8",
64-
"bson": "0E00000002610002000000E90000"
64+
"bson": "0E0000000D610002000000E90000"
6565
}
6666
]
6767
}

test/node/specs/bson-corpus/symbol.json

+7-7
Original file line numberDiff line numberDiff line change
@@ -50,31 +50,31 @@
5050
"decodeErrors": [
5151
{
5252
"description": "bad symbol length: 0 (but no 0x00 either)",
53-
"bson": "0C0000000261000000000000"
53+
"bson": "0C0000000E61000000000000"
5454
},
5555
{
5656
"description": "bad symbol length: -1",
57-
"bson": "0C000000026100FFFFFFFF00"
57+
"bson": "0C0000000E6100FFFFFFFF00"
5858
},
5959
{
6060
"description": "bad symbol length: eats terminator",
61-
"bson": "10000000026100050000006200620000"
61+
"bson": "100000000E6100050000006200620000"
6262
},
6363
{
6464
"description": "bad symbol length: longer than rest of document",
65-
"bson": "120000000200FFFFFF00666F6F6261720000"
65+
"bson": "120000000E00FFFFFF00666F6F6261720000"
6666
},
6767
{
6868
"description": "symbol is not null-terminated",
69-
"bson": "1000000002610004000000616263FF00"
69+
"bson": "100000000E610004000000616263FF00"
7070
},
7171
{
7272
"description": "empty symbol, but extra null",
73-
"bson": "0E00000002610001000000000000"
73+
"bson": "0E0000000E610001000000000000"
7474
},
7575
{
7676
"description": "invalid UTF-8",
77-
"bson": "0E00000002610002000000E90000"
77+
"bson": "0E0000000E610002000000E90000"
7878
}
7979
]
8080
}

0 commit comments

Comments
 (0)