Skip to content

Commit 803d014

Browse files
push for diff
1 parent 65e0e15 commit 803d014

File tree

9 files changed

+89
-208
lines changed

9 files changed

+89
-208
lines changed

src/bson.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,3 +132,14 @@ export function resolveBSONOptions(
132132
options?.enableUtf8Validation ?? parentOptions?.enableUtf8Validation ?? true
133133
};
134134
}
135+
136+
/** @internal */
137+
export function parseUtf8ValidationOption(options?: { enableUtf8Validation?: boolean }): {
138+
utf8: { writeErrors: false } | false;
139+
} {
140+
const enableUtf8Validation = options?.enableUtf8Validation;
141+
if (enableUtf8Validation === false) {
142+
return { utf8: false };
143+
}
144+
return { utf8: { writeErrors: false } };
145+
}

src/cmap/connection.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { type DeserializeOptions } from 'bson';
12
import { type Readable, Transform, type TransformCallback } from 'stream';
23
import { clearTimeout, setTimeout } from 'timers';
34

@@ -487,7 +488,7 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
487488

488489
// If `documentsReturnedIn` not set or raw is not enabled, use input bson options
489490
// Otherwise, support raw flag. Raw only works for cursors that hardcode firstBatch/nextBatch fields
490-
const bsonOptions =
491+
const bsonOptions: DeserializeOptions =
491492
options.documentsReturnedIn == null || !options.raw
492493
? options
493494
: {

src/cmap/wire_protocol/on_demand/document.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1+
import { type DeserializeOptions } from 'bson';
2+
13
import {
24
Binary,
35
type BSONElement,
46
BSONError,
5-
type BSONSerializeOptions,
67
BSONType,
78
deserialize,
89
getBigInt64LE,
910
getFloat64LE,
1011
getInt32LE,
1112
ObjectId,
1213
parseToElementsToArray,
13-
pluckBSONSerializeOptions,
1414
Timestamp,
1515
toUTF8
1616
} from '../../../bson';
@@ -330,14 +330,14 @@ export class OnDemandDocument {
330330
* Deserialize this object, DOES NOT cache result so avoid multiple invocations
331331
* @param options - BSON deserialization options
332332
*/
333-
public toObject(options?: BSONSerializeOptions): Record<string, any> {
334-
const exactBSONOptions = {
335-
...pluckBSONSerializeOptions(options ?? {}),
336-
validation: this.parseBsonSerializationOptions(options),
333+
public toObject(
334+
options?: DeserializeOptions & { validation: NonNullable<DeserializeOptions['validation']> }
335+
): Record<string, any> {
336+
return deserialize(this.bson, {
337+
...options,
337338
index: this.offset,
338339
allowObjectSmallerThanBufferSize: true
339-
};
340-
return deserialize(this.bson, exactBSONOptions);
340+
});
341341
}
342342

343343
private parseBsonSerializationOptions(options?: { enableUtf8Validation?: boolean }): {

src/cmap/wire_protocol/responses.ts

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1+
import { type DeserializeOptions } from 'bson';
2+
13
import {
24
type BSONElement,
35
type BSONSerializeOptions,
46
BSONType,
57
type Document,
68
Long,
79
parseToElementsToArray,
10+
parseUtf8ValidationOption,
11+
pluckBSONSerializeOptions,
812
type Timestamp
913
} from '../../bson';
1014
import { MongoUnexpectedServerResponseError } from '../../error';
@@ -112,7 +116,8 @@ export class MongoDBResponse extends OnDemandDocument {
112116
this.get('recoveryToken', BSONType.object)?.toObject({
113117
promoteValues: false,
114118
promoteLongs: false,
115-
promoteBuffers: false
119+
promoteBuffers: false,
120+
validation: { utf8: true }
116121
}) ?? null
117122
);
118123
}
@@ -165,6 +170,14 @@ export class MongoDBResponse extends OnDemandDocument {
165170
}
166171
return this.clusterTime ?? null;
167172
}
173+
174+
public override toObject(options?: BSONSerializeOptions): Record<string, any> {
175+
const exactBSONOptions = {
176+
...pluckBSONSerializeOptions(options ?? {}),
177+
validation: parseUtf8ValidationOption(options)
178+
};
179+
return super.toObject(exactBSONOptions);
180+
}
168181
}
169182

170183
/** @internal */
@@ -248,12 +261,15 @@ export class CursorResponse extends MongoDBResponse {
248261
this.cursor.get('postBatchResumeToken', BSONType.object)?.toObject({
249262
promoteValues: false,
250263
promoteLongs: false,
251-
promoteBuffers: false
264+
promoteBuffers: false,
265+
validation: { utf8: true }
252266
}) ?? null
253267
);
254268
}
255269

256-
public shift(options?: BSONSerializeOptions): any {
270+
public shift(
271+
options: DeserializeOptions & { validation: NonNullable<DeserializeOptions['validation']> }
272+
): any {
257273
if (this.iterated >= this.batchSize) {
258274
return null;
259275
}
@@ -305,7 +321,7 @@ export class ExplainedCursorResponse extends CursorResponse {
305321
return this._length;
306322
}
307323

308-
override shift(options?: BSONSerializeOptions | undefined) {
324+
override shift(options?: DeserializeOptions) {
309325
if (this._length === 0) return null;
310326
this._length -= 1;
311327
return this.toObject(options);

src/cursor/abstract_cursor.ts

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
1+
import { type DeserializeOptions } from 'bson';
12
import { Readable, Transform } from 'stream';
23

3-
import { type BSONSerializeOptions, type Document, Long, pluckBSONSerializeOptions } from '../bson';
4+
import {
5+
type BSONSerializeOptions,
6+
type Document,
7+
Long,
8+
parseUtf8ValidationOption,
9+
pluckBSONSerializeOptions
10+
} from '../bson';
411
import { type CursorResponse } from '../cmap/wire_protocol/responses';
512
import {
613
MongoAPIError,
@@ -157,6 +164,10 @@ export abstract class AbstractCursor<
157164
/** @event */
158165
static readonly CLOSE = 'close' as const;
159166

167+
protected deserializationOptions: DeserializeOptions & {
168+
validation: NonNullable<DeserializeOptions['validation']>;
169+
};
170+
160171
/** @internal */
161172
protected constructor(
162173
client: MongoClient,
@@ -211,6 +222,11 @@ export abstract class AbstractCursor<
211222
} else {
212223
this.cursorSession = this.cursorClient.startSession({ owner: this, explicit: false });
213224
}
225+
226+
this.deserializationOptions = {
227+
...this.cursorOptions,
228+
validation: parseUtf8ValidationOption(this.cursorOptions)
229+
};
214230
}
215231

216232
/**
@@ -304,7 +320,7 @@ export abstract class AbstractCursor<
304320
);
305321

306322
for (let count = 0; count < documentsToRead; count++) {
307-
const document = this.documents?.shift(this.cursorOptions);
323+
const document = this.documents?.shift(this.deserializationOptions);
308324
if (document != null) {
309325
bufferedDocs.push(document);
310326
}
@@ -406,7 +422,7 @@ export abstract class AbstractCursor<
406422
}
407423

408424
do {
409-
const doc = this.documents?.shift(this.cursorOptions);
425+
const doc = this.documents?.shift(this.deserializationOptions);
410426
if (doc != null) {
411427
if (this.transform != null) return await this.transformDocument(doc);
412428
return doc;
@@ -425,15 +441,15 @@ export abstract class AbstractCursor<
425441
throw new MongoCursorExhaustedError();
426442
}
427443

428-
let doc = this.documents?.shift(this.cursorOptions);
444+
let doc = this.documents?.shift(this.deserializationOptions);
429445
if (doc != null) {
430446
if (this.transform != null) return await this.transformDocument(doc);
431447
return doc;
432448
}
433449

434450
await this.fetchBatch();
435451

436-
doc = this.documents?.shift(this.cursorOptions);
452+
doc = this.documents?.shift(this.deserializationOptions);
437453
if (doc != null) {
438454
if (this.transform != null) return await this.transformDocument(doc);
439455
return doc;

src/cursor/aggregation_cursor.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ export class AggregationCursor<TSchema = any> extends AbstractCursor<TSchema> {
7676
explain: verbosity ?? true
7777
})
7878
)
79-
).shift(this.aggregateOptions);
79+
).shift(this.deserializationOptions);
8080
}
8181

8282
/** Add a stage to the aggregation pipeline

src/cursor/find_cursor.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ export class FindCursor<TSchema = any> extends AbstractCursor<TSchema> {
143143
explain: verbosity ?? true
144144
})
145145
)
146-
).shift(this.findOptions);
146+
).shift(this.deserializationOptions);
147147
}
148148

149149
/** Set the cursor query */

0 commit comments

Comments
 (0)