diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/bson/ordering.h | 8 | ||||
-rw-r--r-- | src/mongo/db/storage/key_string_test.cpp | 25 |
2 files changed, 27 insertions, 6 deletions
diff --git a/src/mongo/bson/ordering.h b/src/mongo/bson/ordering.h index c1052e36a90..db4fc18d06c 100644 --- a/src/mongo/bson/ordering.h +++ b/src/mongo/bson/ordering.h @@ -59,7 +59,13 @@ public: int get(int i) const { uassert(ErrorCodes::Overflow, str::stream() << "Ordering offset is out of bounds: " << i, - i >= 0 && static_cast<size_t>(i) < kMaxCompoundIndexKeys); + i >= 0); + // Ordering only allows the first 32 fields to be inverted; any fields after the 32nd must + // be ascending. Return 1 to avoid a left shift a 32-bit integer by more than 31 bits, which + // is undefined behavior in C++. + if (static_cast<size_t>(i) >= kMaxCompoundIndexKeys) { + return 1; + } return ((1 << i) & bits) ? -1 : 1; } diff --git a/src/mongo/db/storage/key_string_test.cpp b/src/mongo/db/storage/key_string_test.cpp index 32d2919904c..465a43fe1a9 100644 --- a/src/mongo/db/storage/key_string_test.cpp +++ b/src/mongo/db/storage/key_string_test.cpp @@ -205,17 +205,32 @@ TEST(TypeBitsTest, AppendLotsOfZeroTypeBits) { } TEST_F(KeyStringTest, TooManyElementsInCompoundKey) { - // Construct an illegal KeyString with more than the limit of 32 elements in a compound index - // key. Encode 33 kBoolTrue ('o') values. + // Construct a KeyString with more than the limit of 32 elements in a compound index key. Encode + // 33 kBoolTrue ('o') values. + // Note that this KeyString encoding is legal, but it may not be legally stored in an index. const char* data = "ooooooooooooooooooooooooooooooooo"; const size_t size = 33; KeyString ks(KeyString::Version::V1); ks.resetFromBuffer(data, size); - ASSERT_THROWS_CODE(KeyString::toBsonSafe(data, size, ALL_ASCENDING, ks.getTypeBits()), - AssertionException, - ErrorCodes::Overflow); + // No exceptions should be thrown. + KeyString::toBsonSafe(data, size, ALL_ASCENDING, ks.getTypeBits()); + KeyString::getKeySize(ks.getBuffer(), ks.getSize(), ALL_ASCENDING, ks.getTypeBits()); +} + +TEST_F(KeyStringTest, MaxElementsInCompoundKey) { + // Construct a KeyString with 32 elements in a compound index key followed by an end byte. + // Encode 32 kBoolTrue ('o') values and an end byte, 0x4. + const char* data = "oooooooooooooooooooooooooooooooo\x4"; + const size_t size = 33; + + KeyString ks(KeyString::Version::V1); + ks.resetFromBuffer(data, size); + + // No exceptions should be thrown. + KeyString::toBsonSafe(data, size, ALL_ASCENDING, ks.getTypeBits()); + KeyString::getKeySize(ks.getBuffer(), ks.getSize(), ALL_ASCENDING, ks.getTypeBits()); } TEST_F(KeyStringTest, ExceededBSONDepth) { |