diff options
Diffstat (limited to 'src/mongo')
-rw-r--r-- | src/mongo/bson/bsonelement.cpp | 6 | ||||
-rw-r--r-- | src/mongo/bson/bsonelement.h | 15 | ||||
-rw-r--r-- | src/mongo/bson/bsonelement_test.cpp | 15 | ||||
-rw-r--r-- | src/mongo/bson/bsonobjbuilder.h | 7 | ||||
-rw-r--r-- | src/mongo/scripting/mozjs/valuereader.cpp | 2 |
5 files changed, 38 insertions, 7 deletions
diff --git a/src/mongo/bson/bsonelement.cpp b/src/mongo/bson/bsonelement.cpp index c72e61eb888..940589d193b 100644 --- a/src/mongo/bson/bsonelement.cpp +++ b/src/mongo/bson/bsonelement.cpp @@ -213,7 +213,11 @@ void BSONElement::jsonStringStream(JsonStringFormat format, BinDataType type = static_cast<BinDataType>(reader.readAndAdvance<uint8_t>()); s << "{ \"$binary\" : \""; - base64::encode(s, reader.view(), len); + if (type == ByteArrayDeprecated && len >= 4) { + base64::encode(s, reader.view() + 4, len - 4); + } else { + base64::encode(s, reader.view(), len); + } auto origFill = s.fill(); auto origFmtF = s.flags(); diff --git a/src/mongo/bson/bsonelement.h b/src/mongo/bson/bsonelement.h index 892be6df831..d7733b7966a 100644 --- a/src/mongo/bson/bsonelement.h +++ b/src/mongo/bson/bsonelement.h @@ -494,9 +494,18 @@ public: if (binDataType() != ByteArrayDeprecated) { return binData(len); } else { - // Skip extra size - len = valuestrsize() - 4; - return value() + 5 + 4; + // Because, for some time, the shell has incorrectly created type 2 binary objects + // without the extra length, we try to identify if this object does or doesn't start + // with a length and skip past it when its present. See SERVER-41994 + if (valuestrsize() >= 4 && + ConstDataView(value() + 5).read<LittleEndian<int>>() == valuestrsize() - 4) { + // Skip extra size + len = valuestrsize() - 4; + return value() + 5 + 4; + } else { + len = valuestrsize(); + return value() + 5; + } } } diff --git a/src/mongo/bson/bsonelement_test.cpp b/src/mongo/bson/bsonelement_test.cpp index f98ccf93894..b3f6725425f 100644 --- a/src/mongo/bson/bsonelement_test.cpp +++ b/src/mongo/bson/bsonelement_test.cpp @@ -72,6 +72,19 @@ TEST(BSONElement, BinDataToString) { builder.appendBinData( "unknownType", unknownType.size(), unknownBinDataType, unknownType.rawData()); + builder.bb().appendNum((char)BinData); + builder.bb().appendStr("brokenType2"); + builder.bb().appendNum(3); + builder.bb().appendNum((char)ByteArrayDeprecated); + builder.bb().appendBuf("foo", 3); + + builder.bb().appendNum((char)BinData); + builder.bb().appendStr("fixedType2"); + builder.bb().appendNum(4 + 3); + builder.bb().appendNum((char)ByteArrayDeprecated); + builder.bb().appendNum(3); + builder.bb().appendBuf("foo", 3); + BSONObj obj = builder.obj(); ASSERT_EQ(obj["bintype0"].toString(), "bintype0: BinData(0, DEEABEEF01)"); ASSERT_EQ(obj["validUUID"].toString(), "validUUID: UUID(\"" + validUUID.toString() + "\")"); @@ -83,6 +96,8 @@ TEST(BSONElement, BinDataToString) { ASSERT_EQ(obj["unknownType"].toString(), "unknownType: BinData(42, " "62696E6172792064617461007769746820616E20756E6B6E6F776E2074797065)"); + ASSERT_EQ(obj["brokenType2"].toString(), "brokenType2: BinData(2, 666F6F)"); + ASSERT_EQ(obj["fixedType2"].toString(), "fixedType2: BinData(2, 666F6F)"); } diff --git a/src/mongo/bson/bsonobjbuilder.h b/src/mongo/bson/bsonobjbuilder.h index de68ff65353..e520482539e 100644 --- a/src/mongo/bson/bsonobjbuilder.h +++ b/src/mongo/bson/bsonobjbuilder.h @@ -513,6 +513,9 @@ public: int len, BinDataType type, const void* data) { + if (type == ByteArrayDeprecated) { + return appendBinDataArrayDeprecated(fieldName, data, len); + } _b.appendNum((char)BinData); _b.appendStr(fieldName); _b.appendNum(len); @@ -531,11 +534,11 @@ public: @param data a byte array @param len the length of data */ - BSONObjBuilder& appendBinDataArrayDeprecated(const char* fieldName, const void* data, int len) { + BSONObjBuilder& appendBinDataArrayDeprecated(StringData fieldName, const void* data, int len) { _b.appendNum((char)BinData); _b.appendStr(fieldName); _b.appendNum(len + 4); - _b.appendNum((char)0x2); + _b.appendNum((char)ByteArrayDeprecated); _b.appendNum(len); _b.appendBuf(data, len); return *this; diff --git a/src/mongo/scripting/mozjs/valuereader.cpp b/src/mongo/scripting/mozjs/valuereader.cpp index 66a48ddd707..e518cec2e7e 100644 --- a/src/mongo/scripting/mozjs/valuereader.cpp +++ b/src/mongo/scripting/mozjs/valuereader.cpp @@ -136,7 +136,7 @@ void ValueReader::fromBSONElement(const BSONElement& elem, const BSONObj& parent } case mongo::BinData: { int len; - const char* data = elem.binData(len); + const char* data = elem.binDataClean(len); std::stringstream ss; base64::encode(ss, data, len); |