diff options
author | Benety Goh <benety@mongodb.com> | 2021-12-13 12:15:08 -0500 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-12-16 18:53:43 +0000 |
commit | 80d2987ad08a9f6a187b0df19b1ca1d7462a9e02 (patch) | |
tree | c99f42ebd0c5dede38192cd98369019e6e9704ce | |
parent | 817e61d303996e944c4c14e8df14b73f1eb15381 (diff) | |
download | mongo-80d2987ad08a9f6a187b0df19b1ca1d7462a9e02.tar.gz |
SERVER-61846 redact document using null instead of default mask to stay under BSON limit
(cherry picked from commit 886e09ce457d5cdbef16710678c386ec6765db3c)
-rw-r--r-- | src/mongo/bson/bsonobj.cpp | 23 | ||||
-rw-r--r-- | src/mongo/logv2/redaction_test.cpp | 6 |
2 files changed, 21 insertions, 8 deletions
diff --git a/src/mongo/bson/bsonobj.cpp b/src/mongo/bson/bsonobj.cpp index 53c7f313289..33ce012139b 100644 --- a/src/mongo/bson/bsonobj.cpp +++ b/src/mongo/bson/bsonobj.cpp @@ -143,25 +143,38 @@ BSONObj BSONObj::redact() const { // Helper to get an "internal function" to be able to do recursion struct redactor { - void operator()(BSONObjBuilder& builder, const BSONObj& obj) { + void operator()(BSONObjBuilder& builder, const BSONObj& obj, bool appendMask) { for (BSONElement e : obj) { if (e.type() == Object) { BSONObjBuilder subBuilder = builder.subobjStart(e.fieldNameStringData()); - operator()(subBuilder, e.Obj()); + operator()(subBuilder, e.Obj(), appendMask); subBuilder.done(); } else if (e.type() == Array) { BSONObjBuilder subBuilder = builder.subarrayStart(e.fieldNameStringData()); - operator()(subBuilder, e.Obj()); + operator()(subBuilder, e.Obj(), appendMask); subBuilder.done(); - } else { + } else if (appendMask) { builder.append(e.fieldNameStringData(), "###"_sd); + } else { + builder.appendNull(e.fieldNameStringData()); } } } }; + try { + BSONObjBuilder builder; + redactor()(builder, *this, /*appendMask=*/true); + return builder.obj(); + } catch (const ExceptionFor<ErrorCodes::BSONObjectTooLarge>&) { + } + + // For some BSONObj with lots of small fields, replacing each element's value with the default + // redaction mask "###" may cause us to exceed the maximum allowed BSON size. In this case, + // we use BSONType::jstNull, which ensures the redacted object will not be larger than the + // original. BSONObjBuilder builder; - redactor()(builder, *this); + redactor()(builder, *this, /*appendMask=*/false); return builder.obj(); } diff --git a/src/mongo/logv2/redaction_test.cpp b/src/mongo/logv2/redaction_test.cpp index 8ab293822c2..bc22f60b4ae 100644 --- a/src/mongo/logv2/redaction_test.cpp +++ b/src/mongo/logv2/redaction_test.cpp @@ -155,7 +155,7 @@ TEST(RedactBSONTest, BSONWithArrays) { testBSONCases(testCases); } -TEST(RedactBSONTest, RedactCausesBSONTooLarge) { +TEST(RedactBSONTest, RedactedObjectShouldBeSmallerOrEqualInSizeToOriginal) { logv2::setShouldRedactLogs(true); BSONObjBuilder bob; for (int i = 0; i < 1024 * 1024; i++) { @@ -164,8 +164,8 @@ TEST(RedactBSONTest, RedactCausesBSONTooLarge) { bob.append(fieldName, 1); } const auto obj = bob.obj(); - // Demonstrates it is possible to grow a BSON too large by redacting fields. - ASSERT_THROWS_CODE(redact(obj), DBException, ErrorCodes::BSONObjectTooLarge); + const auto redactedObj = redact(obj); + ASSERT_LTE(redactedObj.objsize(), obj.objsize()); } } // namespace } // namespace mongo |