summaryrefslogtreecommitdiff
path: root/src/mongo/bson/bsonobj.cpp
diff options
context:
space:
mode:
authorLucas de Castro Borges <lucas@gnuabordo.com.br>2025-02-18 17:02:53 -0300
committerLucas de Castro Borges <lucas@gnuabordo.com.br>2025-02-18 17:02:53 -0300
commit959575a5ca598bf5f37fb5cebe7ed1d80d3d71f7 (patch)
treeacc8d60aedb12b70048e676e8a7349deb0010db8 /src/mongo/bson/bsonobj.cpp
parent76588293975fc059cf076779e4283e6ffaf8afff (diff)
New upstream version 6.0.20upstream
Diffstat (limited to 'src/mongo/bson/bsonobj.cpp')
-rw-r--r--src/mongo/bson/bsonobj.cpp70
1 files changed, 48 insertions, 22 deletions
diff --git a/src/mongo/bson/bsonobj.cpp b/src/mongo/bson/bsonobj.cpp
index 7b5fa7dae04..f0c5946565c 100644
--- a/src/mongo/bson/bsonobj.cpp
+++ b/src/mongo/bson/bsonobj.cpp
@@ -138,41 +138,71 @@ BSONObj BSONObj::getOwned(const BSONObj& obj) {
return obj.getOwned();
}
-BSONObj BSONObj::redact(bool onlyEncryptedFields) const {
+BSONObj BSONObj::redact(RedactLevel level,
+ std::function<std::string(const BSONElement&)> fieldNameRedactor) const {
_validateUnownedSize(objsize());
// Helper to get an "internal function" to be able to do recursion
struct redactor {
- void appendRedactedElem(BSONObjBuilder& builder, const BSONElement& e, bool appendMask) {
+ void appendRedactedElem(BSONObjBuilder& builder,
+ const StringData& fieldNameString,
+ bool appendMask) {
if (appendMask) {
- builder.append(e.fieldNameStringData(), "###"_sd);
+ builder.append(fieldNameString, "###"_sd);
} else {
- builder.appendNull(e.fieldNameStringData());
+ builder.appendNull(fieldNameString);
}
}
void operator()(BSONObjBuilder& builder,
const BSONObj& obj,
bool appendMask,
- bool onlyEncryptedFields) {
+ RedactLevel level,
+ std::function<std::string(const BSONElement&)> fieldNameRedactor) {
for (BSONElement e : obj) {
+ StringData fieldNameString;
+ // Temporarily allocated string that must live long enough to be copied by builder.
+ std::string tempString;
+ if (!fieldNameRedactor) {
+ fieldNameString = e.fieldNameStringData();
+ } else {
+ tempString = fieldNameRedactor(e);
+ fieldNameString = {tempString};
+ }
if (e.type() == Object) {
- BSONObjBuilder subBuilder = builder.subobjStart(e.fieldNameStringData());
- operator()(subBuilder, e.Obj(), appendMask, onlyEncryptedFields);
+ BSONObjBuilder subBuilder = builder.subobjStart(fieldNameString);
+ operator()(subBuilder, e.Obj(), appendMask, level, fieldNameRedactor);
subBuilder.done();
} else if (e.type() == Array) {
- BSONObjBuilder subBuilder = builder.subarrayStart(e.fieldNameStringData());
- operator()(subBuilder, e.Obj(), appendMask, onlyEncryptedFields);
+ BSONObjBuilder subBuilder = builder.subarrayStart(fieldNameString);
+ operator()(subBuilder, e.Obj(), appendMask, level, fieldNameRedactor);
subBuilder.done();
} else {
- if (onlyEncryptedFields) {
- if (e.type() == BinData && e.binDataType() == BinDataType::Encrypt) {
- appendRedactedElem(builder, e, appendMask);
- } else {
- builder.append(e);
+ // SERVER-79068 Templatizing this could be a good opportunity for performance
+ // improvements.
+ switch (level) {
+ case RedactLevel::all: {
+ appendRedactedElem(builder, fieldNameString, appendMask);
+ break;
+ }
+ case RedactLevel::encryptedAndSensitive: {
+ if (e.type() == BinData &&
+ (e.binDataType() == BinDataType::Encrypt ||
+ e.binDataType() == BinDataType::Sensitive)) {
+ appendRedactedElem(builder, fieldNameString, appendMask);
+ } else {
+ builder.append(e);
+ }
+ break;
+ }
+ case RedactLevel::sensitiveOnly: {
+ if (e.type() == BinData && e.binDataType() == BinDataType::Sensitive) {
+ appendRedactedElem(builder, fieldNameString, appendMask);
+ } else {
+ builder.append(e);
+ }
+ break;
}
- } else {
- appendRedactedElem(builder, e, appendMask);
}
}
}
@@ -181,7 +211,7 @@ BSONObj BSONObj::redact(bool onlyEncryptedFields) const {
try {
BSONObjBuilder builder;
- redactor()(builder, *this, /*appendMask=*/true, onlyEncryptedFields);
+ redactor()(builder, *this, /*appendMask=*/true, level, fieldNameRedactor);
return builder.obj();
} catch (const ExceptionFor<ErrorCodes::BSONObjectTooLarge>&) {
}
@@ -191,7 +221,7 @@ BSONObj BSONObj::redact(bool onlyEncryptedFields) const {
// we use BSONType::jstNull, which ensures the redacted object will not be larger than the
// original.
BSONObjBuilder builder;
- redactor()(builder, *this, /*appendMask=*/false, onlyEncryptedFields);
+ redactor()(builder, *this, /*appendMask=*/false, level, fieldNameRedactor);
return builder.obj();
}
@@ -298,10 +328,6 @@ BSONObj BSONObj::jsonStringBuffer(JsonStringFormat format,
}
}
-bool BSONObj::valid() const {
- return validateBSON(objdata(), objsize()).isOK();
-}
-
int BSONObj::woCompare(const BSONObj& r,
const Ordering& o,
ComparisonRulesSet rules,