@@ -2388,10 +2388,10 @@ BSONObj toBsonSafeWithDiscriminator(const char* buffer,
2388
2388
size_t len,
2389
2389
Ordering ord,
2390
2390
const TypeBits& typeBits) {
2391
- boost::optional<std::string> discriminatorBit ;
2392
- int fieldNo = -1 ;
2391
+ boost::optional<std::string> discriminatorFieldName ;
2392
+ int fieldNo = -1 ; // Record which field should add the discriminator field name.
2393
2393
2394
- // First pass, get the discriminatorBit if there is any.
2394
+ // First pass, get the discriminator byte if there is any.
2395
2395
{
2396
2396
BSONObjBuilder builder;
2397
2397
BufReader reader (buffer, len);
@@ -2400,9 +2400,13 @@ BSONObj toBsonSafeWithDiscriminator(const char* buffer,
2400
2400
const bool invert = (ord.get (i) == -1 );
2401
2401
uint8_t ctype = readType<uint8_t >(&reader, invert);
2402
2402
if (ctype == kLess || ctype == kGreater ) {
2403
- discriminatorBit = ctype == kLess ? " l" : " r" ;
2403
+ // Discriminator byte should not be inverted. It's possible when `ord` has more
2404
+ // fields than keystring and `invert` got mistakenly applied to discriminator byte.
2405
+ if (invert)
2406
+ ctype = ~ctype; // Invert it back.
2407
+ discriminatorFieldName = ctype == kLess ? " l" : " g" ;
2404
2408
fieldNo = i - 1 ;
2405
- ctype = readType<uint8_t >(&reader, invert );
2409
+ ctype = readType<uint8_t >(&reader, false );
2406
2410
invariant (ctype == kEnd );
2407
2411
}
2408
2412
@@ -2413,12 +2417,12 @@ BSONObj toBsonSafeWithDiscriminator(const char* buffer,
2413
2417
toBsonValue (
2414
2418
ctype, &reader, &typeBitsReader, invert, typeBits.version , &(builder << " " ), 1 );
2415
2419
}
2416
- // Early return if there is no discriminatorBit .
2417
- if (!discriminatorBit )
2420
+ // Early return if there is no discriminator byte .
2421
+ if (!discriminatorFieldName )
2418
2422
return builder.obj ();
2419
2423
}
2420
2424
2421
- // Second pass, add discriminatorBit as the fieldName.
2425
+ // Second pass, add discriminator byte as the fieldName.
2422
2426
{
2423
2427
BSONObjBuilder builder;
2424
2428
BufReader reader (buffer, len);
@@ -2427,15 +2431,18 @@ BSONObj toBsonSafeWithDiscriminator(const char* buffer,
2427
2431
const bool invert = (ord.get (i) == -1 );
2428
2432
uint8_t ctype = readType<uint8_t >(&reader, invert);
2429
2433
if (ctype == kLess || ctype == kGreater ) {
2430
- ctype = readType<uint8_t >(&reader, invert);
2434
+ // Invert it back if discriminator byte got mistakenly inverted.
2435
+ if (invert)
2436
+ ctype = ~ctype;
2437
+ ctype = readType<uint8_t >(&reader, false );
2431
2438
invariant (ctype == kEnd );
2432
2439
}
2433
2440
2434
2441
if (ctype == kEnd ) {
2435
2442
break ;
2436
2443
}
2437
2444
2438
- auto fn = i == fieldNo ? discriminatorBit .get () : " " ;
2445
+ auto fn = i == fieldNo ? discriminatorFieldName .get () : " " ;
2439
2446
toBsonValue (
2440
2447
ctype, &reader, &typeBitsReader, invert, typeBits.version , &(builder << fn), 1 );
2441
2448
}
@@ -2457,6 +2464,9 @@ Discriminator decodeDiscriminator(const char* buffer,
2457
2464
const bool invert = (ord.get (i) == -1 );
2458
2465
uint8_t ctype = readType<uint8_t >(&reader, invert);
2459
2466
if (ctype == kLess || ctype == kGreater ) {
2467
+ // Invert it back if discriminator byte got mistakenly inverted.
2468
+ if (invert)
2469
+ ctype = ~ctype;
2460
2470
return ctype == kLess ? Discriminator::kExclusiveBefore
2461
2471
: Discriminator::kExclusiveAfter ;
2462
2472
}
0 commit comments