Skip to content

Commit cafd0e4

Browse files
committed
pr feedback
1 parent a04ec7b commit cafd0e4

11 files changed

Lines changed: 66 additions & 128 deletions

File tree

src/bson.ts

Lines changed: 2 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* eslint-disable no-restricted-imports */
2-
import { BSON, type DeserializeOptions, type SerializeOptions } from 'bson';
2+
import { BSON, type DeserializeOptions, NumberUtils, type SerializeOptions } from 'bson';
33

44
export {
55
Binary,
@@ -39,41 +39,10 @@ export function parseToElementsToArray(bytes: Uint8Array, offset?: number): BSON
3939
return Array.isArray(res) ? res : [...res];
4040
}
4141

42-
export const getInt32LE = BSON.NumberUtils.getInt32LE;
43-
export const getFloat64LE = BSON.NumberUtils.getFloat64LE;
44-
export const getBigInt64LE = BSON.NumberUtils.getBigInt64LE;
45-
export const toUTF8 = BSON.ByteUtils.toUTF8;
46-
export const fromUTF8 = BSON.ByteUtils.fromUTF8;
47-
export const fromBase64 = BSON.ByteUtils.fromBase64;
48-
export const fromNumberArray = BSON.ByteUtils.fromNumberArray;
49-
export const concatBuffers = BSON.ByteUtils.concat;
50-
export const allocateBuffer = BSON.ByteUtils.allocate;
51-
export const allocateUnsafeBuffer = BSON.ByteUtils.allocateUnsafe;
52-
5342
// writeInt32LE, same order of arguments as Buffer.writeInt32LE
5443
export const writeInt32LE = (destination: Uint8Array, value: number, offset: number) =>
5544
BSON.NumberUtils.setInt32LE(destination, offset, value);
5645

57-
// copyBuffer: copies from source buffer to target buffer, returns number of bytes copied
58-
// inputs are explicitly named to avoid confusion
59-
export const copyBuffer = (input: {
60-
source: Uint8Array;
61-
target: Uint8Array;
62-
targetStart?: number;
63-
sourceStart?: number;
64-
sourceEnd?: number;
65-
}): number => {
66-
const { source, target, targetStart = 0, sourceStart = 0, sourceEnd } = input;
67-
const sourceEndActual = sourceEnd ?? source.length;
68-
const srcSlice = source.subarray(sourceStart, sourceEndActual);
69-
const maxLen = Math.min(srcSlice.length, target.length - targetStart);
70-
if (maxLen <= 0) {
71-
return 0;
72-
}
73-
target.set(srcSlice.subarray(0, maxLen), targetStart);
74-
return maxLen;
75-
};
76-
7746
// validates buffer inputs, used for read operations
7847
const validateBufferInputs = (buffer: Uint8Array, offset: number, length: number) => {
7948
if (offset < 0 || offset + length > buffer.length) {
@@ -87,7 +56,7 @@ const validateBufferInputs = (buffer: Uint8Array, offset: number, length: number
8756
// throws if offset is out of bounds
8857
export const readInt32LE = (buffer: Uint8Array, offset: number): number => {
8958
validateBufferInputs(buffer, offset, 4);
90-
return getInt32LE(buffer, offset);
59+
return NumberUtils.getInt32LE(buffer, offset);
9160
};
9261

9362
/**

src/cmap/auth/plain.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Binary, fromUTF8 } from '../../bson';
1+
import { Binary, ByteUtils } from '../../bson';
22
import { MongoMissingCredentialsError } from '../../error';
33
import { ns } from '../../utils';
44
import { type AuthContext, AuthProvider } from './auth_provider';
@@ -12,7 +12,7 @@ export class Plain extends AuthProvider {
1212

1313
const { username, password } = credentials;
1414

15-
const payload = new Binary(fromUTF8(`\x00${username}\x00${password}`));
15+
const payload = new Binary(ByteUtils.fromUTF8(`\x00${username}\x00${password}`));
1616
const command = {
1717
saslStart: 1,
1818
mechanism: 'PLAIN',

src/cmap/auth/scram.ts

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,7 @@
11
import { saslprep } from '@mongodb-js/saslprep';
22
import * as crypto from 'crypto';
33

4-
import {
5-
allocateBuffer,
6-
Binary,
7-
ByteUtils,
8-
concatBuffers,
9-
type Document,
10-
fromBase64,
11-
fromNumberArray,
12-
fromUTF8
13-
} from '../../bson';
4+
import { Binary, ByteUtils, type Document } from '../../bson';
145
import {
156
MongoInvalidArgumentError,
167
MongoMissingCredentialsError,
@@ -77,11 +68,11 @@ function cleanUsername(username: string) {
7768
function clientFirstMessageBare(username: string, nonce: Uint8Array) {
7869
// NOTE: This is done b/c Javascript uses UTF-16, but the server is hashing in UTF-8.
7970
// Since the username is not sasl-prep-d, we need to do this here.
80-
return concatBuffers([
81-
fromUTF8('n='),
82-
fromUTF8(username),
83-
fromUTF8(',r='),
84-
fromUTF8(ByteUtils.toBase64(nonce))
71+
return ByteUtils.concat([
72+
ByteUtils.fromUTF8('n='),
73+
ByteUtils.fromUTF8(username),
74+
ByteUtils.fromUTF8(',r='),
75+
ByteUtils.fromUTF8(ByteUtils.toBase64(nonce))
8576
]);
8677
}
8778

@@ -99,7 +90,9 @@ function makeFirstMessage(
9990
return {
10091
saslStart: 1,
10192
mechanism,
102-
payload: new Binary(concatBuffers([fromUTF8('n,,'), clientFirstMessageBare(username, nonce)])),
93+
payload: new Binary(
94+
ByteUtils.concat([ByteUtils.fromUTF8('n,,'), clientFirstMessageBare(username, nonce)])
95+
),
10396
autoAuthorize: 1,
10497
options: { skipEmptyExchange: true }
10598
};
@@ -164,7 +157,12 @@ async function continueScramConversation(
164157

165158
// Set up start of proof
166159
const withoutProof = `c=biws,r=${rnonce}`;
167-
const saltedPassword = HI(processedPassword, fromBase64(salt), iterations, cryptoMethod);
160+
const saltedPassword = HI(
161+
processedPassword,
162+
ByteUtils.fromBase64(salt),
163+
iterations,
164+
cryptoMethod
165+
);
168166

169167
const clientKey = HMAC(cryptoMethod, saltedPassword, 'Client Key');
170168
const serverKey = HMAC(cryptoMethod, saltedPassword, 'Server Key');
@@ -183,13 +181,13 @@ async function continueScramConversation(
183181
const saslContinueCmd = {
184182
saslContinue: 1,
185183
conversationId: response.conversationId,
186-
payload: new Binary(fromUTF8(clientFinal))
184+
payload: new Binary(ByteUtils.fromUTF8(clientFinal))
187185
};
188186

189187
const r = await connection.command(ns(`${db}.$cmd`), saslContinueCmd, undefined);
190188
const parsedResponse = parsePayload(r.payload);
191189

192-
if (!compareDigest(fromBase64(parsedResponse.v), serverSignature)) {
190+
if (!compareDigest(ByteUtils.fromBase64(parsedResponse.v), serverSignature)) {
193191
throw new MongoRuntimeError('Server returned an invalid signature');
194192
}
195193

@@ -201,7 +199,7 @@ async function continueScramConversation(
201199
const retrySaslContinueCmd = {
202200
saslContinue: 1,
203201
conversationId: r.conversationId,
204-
payload: allocateBuffer(0)
202+
payload: ByteUtils.allocate(0)
205203
};
206204

207205
await connection.command(ns(`${db}.$cmd`), retrySaslContinueCmd, undefined);
@@ -255,7 +253,7 @@ function xor(a: Uint8Array, b: Uint8Array) {
255253
res.push(a[i] ^ b[i]);
256254
}
257255

258-
return ByteUtils.toBase64(fromNumberArray(res));
256+
return ByteUtils.toBase64(ByteUtils.fromNumberArray(res));
259257
}
260258

261259
function H(method: CryptoMethod, text: Uint8Array): Uint8Array {

src/cmap/commands.ts

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
import {
2-
allocateBuffer,
3-
allocateUnsafeBuffer,
42
BSON,
53
type BSONSerializeOptions,
64
ByteUtils,
7-
concatBuffers,
85
type Document,
96
type Long,
107
readInt32LE,
@@ -192,7 +189,7 @@ export class OpQueryRequest {
192189
if (this.batchSize !== this.numberToReturn) this.numberToReturn = this.batchSize;
193190

194191
// Allocate write protocol header buffer
195-
const header = allocateBuffer(
192+
const header = ByteUtils.allocate(
196193
4 * 4 + // Header
197194
4 + // Flags
198195
ByteUtils.utf8ByteLength(this.ns) +
@@ -456,7 +453,7 @@ export class DocumentSequence {
456453
this.serializedDocumentsLength = 0;
457454
// Document sequences starts with type 1 at the first byte.
458455
// Field strings must always be UTF-8.
459-
const buffer = allocateUnsafeBuffer(1 + 4 + this.field.length + 1);
456+
const buffer = ByteUtils.allocateUnsafe(1 + 4 + this.field.length + 1);
460457
buffer[0] = 1;
461458
// Third part is the field name at offset 5 with trailing null byte.
462459
encodeUTF8Into(buffer, `${this.field}\0`, 5);
@@ -494,7 +491,7 @@ export class DocumentSequence {
494491
* @returns The section bytes.
495492
*/
496493
toBin(): Uint8Array {
497-
return concatBuffers(this.chunks);
494+
return ByteUtils.concat(this.chunks);
498495
}
499496
}
500497

@@ -559,7 +556,7 @@ export class OpMsgRequest {
559556
flags |= OPTS_EXHAUST_ALLOWED;
560557
}
561558

562-
const header = allocateBuffer(
559+
const header = ByteUtils.allocate(
563560
4 * 4 + // Header
564561
4 // Flags
565562
);
@@ -583,7 +580,7 @@ export class OpMsgRequest {
583580
*/
584581
makeSections(buffers: Uint8Array[], document: Document): number {
585582
const sequencesBuffer = this.extractDocumentSequences(document);
586-
const payloadTypeBuffer = allocateUnsafeBuffer(1);
583+
const payloadTypeBuffer = ByteUtils.allocateUnsafe(1);
587584
payloadTypeBuffer[0] = 0;
588585

589586
const documentBuffer = this.serializeBson(document);
@@ -618,11 +615,11 @@ export class OpMsgRequest {
618615
}
619616
}
620617
if (chunks.length > 0) {
621-
return concatBuffers(chunks);
618+
return ByteUtils.concat(chunks);
622619
}
623620
// If we have no document sequences we return an empty buffer for nothing to add
624621
// to the payload.
625-
return allocateBuffer(0);
622+
return ByteUtils.allocate(0);
626623
}
627624

628625
serializeBson(document: Document): Uint8Array {
@@ -771,7 +768,7 @@ export class OpCompressedRequest {
771768
}
772769

773770
async toBin(): Promise<Uint8Array[]> {
774-
const concatenatedOriginalCommandBuffer = concatBuffers(this.command.toBin());
771+
const concatenatedOriginalCommandBuffer = ByteUtils.concat(this.command.toBin());
775772
// otherwise, compress the message
776773
const messageToBeCompressed = concatenatedOriginalCommandBuffer.slice(MESSAGE_HEADER_SIZE);
777774

@@ -781,7 +778,7 @@ export class OpCompressedRequest {
781778
// Compress the message body
782779
const compressedMessage = await compress(this.options, messageToBeCompressed);
783780
// Create the msgHeader of OP_COMPRESSED
784-
const msgHeader = allocateBuffer(MESSAGE_HEADER_SIZE);
781+
const msgHeader = ByteUtils.allocate(MESSAGE_HEADER_SIZE);
785782
writeInt32LE(
786783
msgHeader,
787784
MESSAGE_HEADER_SIZE + COMPRESSION_DETAILS_SIZE + compressedMessage.length,
@@ -791,7 +788,7 @@ export class OpCompressedRequest {
791788
writeInt32LE(msgHeader, 0, 8); // responseTo (zero)
792789
writeInt32LE(msgHeader, OP_COMPRESSED, 12); // opCode
793790
// Create the compression details of OP_COMPRESSED
794-
const compressionDetails = allocateBuffer(COMPRESSION_DETAILS_SIZE);
791+
const compressionDetails = ByteUtils.allocate(COMPRESSION_DETAILS_SIZE);
795792
writeInt32LE(compressionDetails, originalCommandOpCode, 0); // originalOpcode
796793
writeInt32LE(compressionDetails, messageToBeCompressed.length, 4); // Size of the uncompressed compressedMessage, excluding the MsgHeader
797794
writeInt32LE(compressionDetails, Compressor[this.options.agreedCompressor], 8); // compressorID

src/cmap/connection.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { clearTimeout, setTimeout } from 'timers';
44
import {
55
BSON,
66
type BSONSerializeOptions,
7-
concatBuffers,
7+
ByteUtils,
88
deserialize,
99
type DeserializeOptions,
1010
type Document,
@@ -698,7 +698,7 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
698698
zlibCompressionLevel: options.zlibCompressionLevel ?? 0
699699
});
700700

701-
const buffer = concatBuffers(await finalCommand.toBin());
701+
const buffer = ByteUtils.concat(await finalCommand.toBin());
702702

703703
if (options.timeoutContext?.csotEnabled()) {
704704
if (

src/cmap/handshake/client_metadata.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as os from 'os';
22
import * as process from 'process';
33

4-
import { BSON, type Document, fromUTF8, Int32, toUTF8 } from '../../bson';
4+
import { BSON, ByteUtils, type Document, Int32 } from '../../bson';
55
import { MongoInvalidArgumentError } from '../../error';
66
import type { DriverInfo, MongoOptions } from '../../mongo_client';
77
import { fileIsAccessible } from '../../utils';
@@ -116,7 +116,7 @@ export async function makeClientMetadata(
116116
const name =
117117
BSON.ByteUtils.utf8ByteLength(appName) <= 128
118118
? appName
119-
: toUTF8(fromUTF8(appName), 0, 128, false);
119+
: ByteUtils.toUTF8(ByteUtils.fromUTF8(appName), 0, 128, false);
120120
metadataDocument.ifItFitsItSits('application', { name });
121121
}
122122

src/cmap/wire_protocol/compression.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as zlib from 'zlib';
22

3-
import { concatBuffers, readInt32LE } from '../../bson';
3+
import { ByteUtils, readInt32LE } from '../../bson';
44
import { LEGACY_HELLO_COMMAND } from '../../constants';
55
import { getSnappy, getZstdLibrary, type SnappyLib, type ZStandard } from '../../deps';
66
import { MongoDecompressionError, MongoInvalidArgumentError } from '../../error';
@@ -172,7 +172,7 @@ export async function compressCommand(
172172
zlibCompressionLevel: description.zlibCompressionLevel ?? 0
173173
});
174174
const data = await finalCommand.toBin();
175-
return concatBuffers(data);
175+
return ByteUtils.concat(data);
176176
}
177177

178178
/**

src/cmap/wire_protocol/on_demand/document.ts

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,13 @@ import {
33
type BSONElement,
44
BSONError,
55
BSONType,
6+
ByteUtils,
67
deserialize,
78
type DeserializeOptions,
8-
getBigInt64LE,
9-
getFloat64LE,
10-
getInt32LE,
9+
NumberUtils,
1110
ObjectId,
1211
parseToElementsToArray,
13-
Timestamp,
14-
toUTF8
12+
Timestamp
1513
} from '../../../bson';
1614

1715
const BSONElementOffset = {
@@ -183,25 +181,25 @@ export class OnDemandDocument {
183181
case BSONType.undefined:
184182
return null;
185183
case BSONType.double:
186-
return getFloat64LE(this.bson, offset);
184+
return NumberUtils.getFloat64LE(this.bson, offset);
187185
case BSONType.int:
188-
return getInt32LE(this.bson, offset);
186+
return NumberUtils.getInt32LE(this.bson, offset);
189187
case BSONType.long:
190-
return getBigInt64LE(this.bson, offset);
188+
return NumberUtils.getBigInt64LE(this.bson, offset);
191189
case BSONType.bool:
192190
return Boolean(this.bson[offset]);
193191
case BSONType.objectId:
194192
return new ObjectId(this.bson.subarray(offset, offset + 12));
195193
case BSONType.timestamp:
196-
return new Timestamp(getBigInt64LE(this.bson, offset));
194+
return new Timestamp(NumberUtils.getBigInt64LE(this.bson, offset));
197195
case BSONType.string:
198-
return toUTF8(this.bson, offset + 4, offset + length - 1, false);
196+
return ByteUtils.toUTF8(this.bson, offset + 4, offset + length - 1, false);
199197
case BSONType.binData: {
200-
const totalBinarySize = getInt32LE(this.bson, offset);
198+
const totalBinarySize = NumberUtils.getInt32LE(this.bson, offset);
201199
const subType = this.bson[offset + 4];
202200

203201
if (subType === 2) {
204-
const subType2BinarySize = getInt32LE(this.bson, offset + 1 + 4);
202+
const subType2BinarySize = NumberUtils.getInt32LE(this.bson, offset + 1 + 4);
205203
if (subType2BinarySize < 0)
206204
throw new BSONError('Negative binary type element size found for subtype 0x02');
207205
if (subType2BinarySize > totalBinarySize - 4)
@@ -221,7 +219,7 @@ export class OnDemandDocument {
221219
}
222220
case BSONType.date:
223221
// Pretend this is correct.
224-
return new Date(Number(getBigInt64LE(this.bson, offset)));
222+
return new Date(Number(NumberUtils.getBigInt64LE(this.bson, offset)));
225223

226224
case BSONType.object:
227225
return new OnDemandDocument(this.bson, offset);
@@ -352,7 +350,7 @@ export class OnDemandDocument {
352350

353351
/** Returns this document's bytes only */
354352
toBytes() {
355-
const size = getInt32LE(this.bson, this.offset);
353+
const size = NumberUtils.getInt32LE(this.bson, this.offset);
356354
return this.bson.subarray(this.offset, this.offset + size);
357355
}
358356
}

0 commit comments

Comments
 (0)