@@ -2388,10 +2388,10 @@ BSONObj toBsonSafeWithDiscriminator(const char* buffer,
23882388 size_t len,
23892389 Ordering ord,
23902390 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.
23932393
2394- // First pass, get the discriminatorBit if there is any.
2394+ // First pass, get the discriminator byte if there is any.
23952395 {
23962396 BSONObjBuilder builder;
23972397 BufReader reader (buffer, len);
@@ -2400,9 +2400,13 @@ BSONObj toBsonSafeWithDiscriminator(const char* buffer,
24002400 const bool invert = (ord.get (i) == -1 );
24012401 uint8_t ctype = readType<uint8_t >(&reader, invert);
24022402 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" ;
24042408 fieldNo = i - 1 ;
2405- ctype = readType<uint8_t >(&reader, invert );
2409+ ctype = readType<uint8_t >(&reader, false );
24062410 invariant (ctype == kEnd );
24072411 }
24082412
@@ -2413,12 +2417,12 @@ BSONObj toBsonSafeWithDiscriminator(const char* buffer,
24132417 toBsonValue (
24142418 ctype, &reader, &typeBitsReader, invert, typeBits.version , &(builder << " " ), 1 );
24152419 }
2416- // Early return if there is no discriminatorBit .
2417- if (!discriminatorBit )
2420+ // Early return if there is no discriminator byte .
2421+ if (!discriminatorFieldName )
24182422 return builder.obj ();
24192423 }
24202424
2421- // Second pass, add discriminatorBit as the fieldName.
2425+ // Second pass, add discriminator byte as the fieldName.
24222426 {
24232427 BSONObjBuilder builder;
24242428 BufReader reader (buffer, len);
@@ -2427,15 +2431,18 @@ BSONObj toBsonSafeWithDiscriminator(const char* buffer,
24272431 const bool invert = (ord.get (i) == -1 );
24282432 uint8_t ctype = readType<uint8_t >(&reader, invert);
24292433 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 );
24312438 invariant (ctype == kEnd );
24322439 }
24332440
24342441 if (ctype == kEnd ) {
24352442 break ;
24362443 }
24372444
2438- auto fn = i == fieldNo ? discriminatorBit .get () : " " ;
2445+ auto fn = i == fieldNo ? discriminatorFieldName .get () : " " ;
24392446 toBsonValue (
24402447 ctype, &reader, &typeBitsReader, invert, typeBits.version , &(builder << fn), 1 );
24412448 }
@@ -2457,6 +2464,9 @@ Discriminator decodeDiscriminator(const char* buffer,
24572464 const bool invert = (ord.get (i) == -1 );
24582465 uint8_t ctype = readType<uint8_t >(&reader, invert);
24592466 if (ctype == kLess || ctype == kGreater ) {
2467+ // Invert it back if discriminator byte got mistakenly inverted.
2468+ if (invert)
2469+ ctype = ~ctype;
24602470 return ctype == kLess ? Discriminator::kExclusiveBefore
24612471 : Discriminator::kExclusiveAfter ;
24622472 }
0 commit comments