summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Noma <gregory.noma@gmail.com>2022-09-08 20:39:50 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-09-08 22:23:07 +0000
commit7a3301774c0c3031ac724c25e24f005d45de4320 (patch)
tree83bf3596c9e6c98617c06fe4703b78b4023523b5
parent5622c8b6c3d7283421347bc8042afa20c4c3d769 (diff)
downloadmongo-7a3301774c0c3031ac724c25e24f005d45de4320.tar.gz
SERVER-67855 Throw on invalid delta in BSON Column encoding
-rw-r--r--src/mongo/bson/util/bsoncolumn.cpp8
-rw-r--r--src/mongo/bson/util/bsoncolumn_test.cpp56
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);