diff options
author | Gregory Noma <gregory.noma@gmail.com> | 2022-09-08 20:39:50 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-09-08 22:23:07 +0000 |
commit | 7a3301774c0c3031ac724c25e24f005d45de4320 (patch) | |
tree | 83bf3596c9e6c98617c06fe4703b78b4023523b5 | |
parent | 5622c8b6c3d7283421347bc8042afa20c4c3d769 (diff) | |
download | mongo-7a3301774c0c3031ac724c25e24f005d45de4320.tar.gz |
SERVER-67855 Throw on invalid delta in BSON Column encoding
-rw-r--r-- | src/mongo/bson/util/bsoncolumn.cpp | 8 | ||||
-rw-r--r-- | src/mongo/bson/util/bsoncolumn_test.cpp | 56 |
2 files changed, 64 insertions, 0 deletions
diff --git a/src/mongo/bson/util/bsoncolumn.cpp b/src/mongo/bson/util/bsoncolumn.cpp index aa81339f9aa..3308dac7b3b 100644 --- a/src/mongo/bson/util/bsoncolumn.cpp +++ b/src/mongo/bson/util/bsoncolumn.cpp @@ -724,6 +724,14 @@ BSONElement BSONColumn::Iterator::DecodingState::_loadDelta(BSONColumn& column, case bsonTimestamp: { DataView(elem.value()).write<LittleEndian<long long>>(valueToWrite); } break; + case RegEx: + case DBRef: + case CodeWScope: + case Symbol: + case Object: + case Array: + case EOO: // EOO indicates the end of an interleaved object. + uasserted(6785500, "Invalid delta in BSON Column encoding"); default: // No other types use int64 and need to allocate value storage MONGO_UNREACHABLE; diff --git a/src/mongo/bson/util/bsoncolumn_test.cpp b/src/mongo/bson/util/bsoncolumn_test.cpp index 0ab624d1f85..9eafed3c110 100644 --- a/src/mongo/bson/util/bsoncolumn_test.cpp +++ b/src/mongo/bson/util/bsoncolumn_test.cpp @@ -494,6 +494,21 @@ public: } } + /** + * Constructs a BSON Column encoding with a non-zero delta after the specified element, and + * expects error 6785500 to be thrown. + */ + void testInvalidDelta(BSONElement elem) { + BufBuilder expected; + appendLiteral(expected, elem); + appendSimple8bControl(expected, 0b1000, 0b0000); + appendSimple8bBlock64(expected, Simple8bTypeUtil::encodeInt64(1)); + appendEOO(expected); + + BSONColumn col(createBSONColumn(expected.buf(), expected.len())); + ASSERT_THROWS_CODE(std::distance(col.begin(), col.end()), DBException, 6785500); + } + const boost::optional<uint64_t> kDeltaForBinaryEqualValues = Simple8bTypeUtil::encodeInt64(0); const boost::optional<uint128_t> kDeltaForBinaryEqualValues128 = Simple8bTypeUtil::encodeInt128(0); @@ -5235,6 +5250,47 @@ TEST_F(BSONColumnTest, InvalidInterleavedWhenAlreadyInterleaved) { ASSERT_THROWS(std::distance(col.begin(), col.end()), DBException); } +TEST_F(BSONColumnTest, InvalidDeltaAfterInterleaved) { + // This test uses a non-zero delta value after an interleaved object, which is invalid. + auto test = [&](bool arrayCompression, auto appendInterleavedStartFunc) { + BufBuilder expected; + appendInterleavedStartFunc(expected, BSON("a" << 1)); + appendSimple8bControl(expected, 0b1000, 0b0000); + appendSimple8bBlocks64(expected, {kDeltaForBinaryEqualValues}, 1); + appendEOO(expected); + appendSimple8bControl(expected, 0b1000, 0b0000); + appendSimple8bBlock64(expected, Simple8bTypeUtil::encodeInt64(1)); + appendEOO(expected); + + BSONColumn col(createBSONColumn(expected.buf(), expected.len())); + ASSERT_THROWS_CODE(std::distance(col.begin(), col.end()), DBException, 6785500); + }; + + test(false, appendInterleavedStartLegacy); + test(true, appendInterleavedStart); + + BufBuilder expected; + appendInterleavedStartArrayRoot(expected, BSON_ARRAY(1)); + appendSimple8bControl(expected, 0b1000, 0b0000); + appendSimple8bBlocks64(expected, {kDeltaForBinaryEqualValues}, 1); + appendEOO(expected); + appendSimple8bControl(expected, 0b1000, 0b0000); + appendSimple8bBlock64(expected, Simple8bTypeUtil::encodeInt64(1)); + appendEOO(expected); + + BSONColumn col(createBSONColumn(expected.buf(), expected.len())); + ASSERT_THROWS_CODE(std::distance(col.begin(), col.end()), DBException, 6785500); +} + +TEST_F(BSONColumnTest, InvalidDelta) { + testInvalidDelta(createRegex()); + testInvalidDelta(createDBRef("ns", OID{"112233445566778899AABBCC"})); + testInvalidDelta(createCodeWScope("code", BSONObj{})); + testInvalidDelta(createSymbol("symbol")); + testInvalidDelta(BSON("obj" << BSON("a" << 1)).firstElement()); + testInvalidDelta(BSON("arr" << BSON_ARRAY("a")).firstElement()); +} + TEST_F(BSONColumnTest, AppendMinKey) { BSONColumnBuilder cb("test"); ASSERT_THROWS_CODE(cb.append(createElementMinKey()), DBException, ErrorCodes::InvalidBSONType); |