Skip to content

Commit

Permalink
fix(bson): throw on invalid string data
Browse files Browse the repository at this point in the history
for invalid buffer is received is it necessary to check buffer size to not endlessly loop to find the end of a string.
  • Loading branch information
marcj committed Jan 9, 2025
1 parent fb1263d commit 423df6c
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 2 deletions.
7 changes: 5 additions & 2 deletions packages/bson/src/bson-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,14 +279,17 @@ export class BaseParser {
*/
stringSize(): number {
let end = this.offset;
while (this.buffer[end] !== 0) end++;
while (this.buffer[end] !== 0 && end < this.size) end++;
end++; //null
return end - this.offset;
}

eatObjectPropertyName() {
let end = this.offset;
while (this.buffer[end] !== 0) end++;
while (this.buffer[end] !== 0) {
if (end >= this.size) throw new SerializationError('Unexpected end of buffer');
end++;
}
const s = decodeUTF8(this.buffer, this.offset, end);
this.offset = end + 1;
return s;
Expand Down
19 changes: 19 additions & 0 deletions packages/bson/tests/bson-parser.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { deserializeBSON, getBSONDeserializer } from '../src/bson-deserializer.j
import { BinaryBigInt, copyAndSetParent, MongoId, nodeBufferToArrayBuffer, PrimaryKey, Reference, ReflectionKind, SignedBinaryBigInt, TypeObjectLiteral, typeOf, uuid, UUID } from '@deepkit/type';
import { getClassName } from '@deepkit/core';
import { serializeBSONWithoutOptimiser } from '../src/bson-serializer.js';
import { BSONType } from '../src/utils';
import { deserializeBSONWithoutOptimiser } from '../src/bson-parser';

const { deserialize, serialize } = bson;

Expand Down Expand Up @@ -754,3 +756,20 @@ test('additional are ignored', () => {
const back = fn(bson);
expect(back).toEqual({ismaster: true});
});

test('invalid buffer, string parse', () => {
const buffer = Buffer.from([
28, 0, 0, 0, //size
BSONType.BINARY, //just some type
112, 111, 115, 105, 116, 105, 111, 110, // 0, /'/position\n' without ending
// to simulate a buffer that is not correctly serialized
]);

expect(() => deserializeBSONWithoutOptimiser(buffer)).toThrow('Unexpected end of buffer');

const deserialize = getBSONDeserializer<{ position: Uint8Array }>();
expect(() => deserialize(buffer)).toThrow('Cannot convert undefined value to Uint8Array');

const deserialize2 = getBSONDeserializer<{ [name: string]: Uint8Array }>();
expect(() => deserialize2(buffer)).toThrow('Serialization failed. Unexpected end of buffer');
});

0 comments on commit 423df6c

Please sign in to comment.