summaryrefslogtreecommitdiff
path: root/src/mongo/rpc/op_msg.cpp
diff options
context:
space:
mode:
authorSpencer T Brody <spencer@mongodb.com>2020-04-16 21:06:38 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-04-20 22:02:48 +0000
commit41bec612516c3258984deaa022453d6721bcd542 (patch)
tree48e3646244e3688f695d547e49e69c651aa34d1d /src/mongo/rpc/op_msg.cpp
parent010817217033f0007646b44f21f0c2862a1b22e6 (diff)
downloadmongo-41bec612516c3258984deaa022453d6721bcd542.tar.gz
SERVER-43328 Enforce BSON size limit in OpMsgBuilder
Diffstat (limited to 'src/mongo/rpc/op_msg.cpp')
-rw-r--r--src/mongo/rpc/op_msg.cpp33
1 files changed, 29 insertions, 4 deletions
diff --git a/src/mongo/rpc/op_msg.cpp b/src/mongo/rpc/op_msg.cpp
index d29b5ac2578..ca699693170 100644
--- a/src/mongo/rpc/op_msg.cpp
+++ b/src/mongo/rpc/op_msg.cpp
@@ -229,18 +229,32 @@ OpMsg OpMsg::parse(const Message& message) try {
throw;
}
-Message OpMsg::serialize() const {
- OpMsgBuilder builder;
+namespace {
+void serializeHelper(const std::vector<OpMsg::DocumentSequence>& sequences,
+ const BSONObj& body,
+ OpMsgBuilder* output) {
for (auto&& seq : sequences) {
- auto docSeq = builder.beginDocSequence(seq.name);
+ auto docSeq = output->beginDocSequence(seq.name);
for (auto&& obj : seq.objs) {
docSeq.append(obj);
}
}
- builder.beginBody().appendElements(body);
+ output->beginBody().appendElements(body);
+}
+} // namespace
+
+Message OpMsg::serialize() const {
+ OpMsgBuilder builder;
+ serializeHelper(sequences, body, &builder);
return builder.finish();
}
+Message OpMsg::serializeWithoutSizeChecking() const {
+ OpMsgBuilder builder;
+ serializeHelper(sequences, body, &builder);
+ return builder.finishWithoutSizeChecking();
+}
+
void OpMsg::shareOwnershipWith(const ConstSharedBuffer& buffer) {
if (!body.isOwned()) {
body.shareOwnershipWith(buffer);
@@ -293,6 +307,17 @@ BSONObjBuilder OpMsgBuilder::resumeBody() {
AtomicWord<bool> OpMsgBuilder::disableDupeFieldCheck_forTest{false};
Message OpMsgBuilder::finish() {
+ const auto size = _buf.len();
+ uassert(ErrorCodes::BSONObjectTooLarge,
+ str::stream() << "BSON size limit hit while building Message. Size: " << size << " (0x"
+ << integerToHex(size) << "); maxSize: " << BSONObjMaxInternalSize << "("
+ << (BSONObjMaxInternalSize / (1024 * 1024)) << "MB)",
+ size <= BSONObjMaxInternalSize);
+
+ return finishWithoutSizeChecking();
+}
+
+Message OpMsgBuilder::finishWithoutSizeChecking() {
if (kDebugBuild && !disableDupeFieldCheck_forTest.load()) {
std::set<StringData> seenFields;
for (auto elem : resumeBody().asTempObj()) {