summaryrefslogtreecommitdiff
path: root/src/mongo/bson/bsonobj.cpp
diff options
context:
space:
mode:
authorJess Balint <jbalint@gmail.com>2022-11-15 05:07:22 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-11-15 06:30:53 +0000
commit7be344b92d3af3fd8eb4542e594e084bed394fdc (patch)
tree8fb77406d0eb74fe46854c121454ddd7327cec3e /src/mongo/bson/bsonobj.cpp
parent148c522ffefc93dcc8227579b583691335cd4f2f (diff)
downloadmongo-7be344b92d3af3fd8eb4542e594e084bed394fdc.tar.gz
SERVER-71292 Redact all sensitive information in query #8731
Diffstat (limited to 'src/mongo/bson/bsonobj.cpp')
-rw-r--r--src/mongo/bson/bsonobj.cpp41
1 files changed, 28 insertions, 13 deletions
diff --git a/src/mongo/bson/bsonobj.cpp b/src/mongo/bson/bsonobj.cpp
index c462031bffd..88715dd68de 100644
--- a/src/mongo/bson/bsonobj.cpp
+++ b/src/mongo/bson/bsonobj.cpp
@@ -145,41 +145,56 @@ BSONObj BSONObj::getOwned(const BSONObj& obj) {
return obj.getOwned();
}
-BSONObj BSONObj::redact(bool onlyEncryptedFields) const {
+BSONObj BSONObj::redact(bool onlyEncryptedFields,
+ 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) {
+ bool onlyEncryptedFields,
+ 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, onlyEncryptedFields, 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, onlyEncryptedFields, fieldNameRedactor);
subBuilder.done();
} else {
if (onlyEncryptedFields) {
if (e.type() == BinData && e.binDataType() == BinDataType::Encrypt) {
- appendRedactedElem(builder, e, appendMask);
+ appendRedactedElem(builder, fieldNameString, appendMask);
} else {
builder.append(e);
}
} else {
- appendRedactedElem(builder, e, appendMask);
+ appendRedactedElem(builder, fieldNameString, appendMask);
}
}
}
@@ -188,7 +203,7 @@ BSONObj BSONObj::redact(bool onlyEncryptedFields) const {
try {
BSONObjBuilder builder;
- redactor()(builder, *this, /*appendMask=*/true, onlyEncryptedFields);
+ redactor()(builder, *this, /*appendMask=*/true, onlyEncryptedFields, fieldNameRedactor);
return builder.obj();
} catch (const ExceptionFor<ErrorCodes::BSONObjectTooLarge>&) {
}
@@ -198,7 +213,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, onlyEncryptedFields, fieldNameRedactor);
return builder.obj();
}