SERVER-115438 Make minimally sized buffers for uncompressed Messages (#45581)

Co-authored-by: Spencer Jackson <spencer.jackson@mongodb.com>
GitOrigin-RevId: 25381e40e8f1a2c00d03a93a93eb7e9cbd36ba21
This commit is contained in:
Mark Benvenuto 2025-12-23 03:01:15 -08:00 committed by MongoDB Bot
parent 82f22ff185
commit ed46e9c63a
2 changed files with 67 additions and 1 deletions

View File

@ -189,6 +189,26 @@ void checkOverflow(std::unique_ptr<MessageCompressorBase> compressor) {
compressor->decompressData(tooSmallRange, DataRange(scratch.data(), scratch.size())));
}
void checkUndersize(const Message& compressedMsg,
std::unique_ptr<MessageCompressorBase> compressor) {
MessageCompressorRegistry registry;
const auto compressorName = compressor->getName();
std::vector<std::string> compressorList = {compressorName};
registry.setSupportedCompressors(std::move(compressorList));
registry.registerImplementation(std::move(compressor));
registry.finalizeSupportedCompressors().transitional_ignore();
MessageCompressorManager mgr(&registry);
BSONObjBuilder negotiatorOut;
std::vector<StringData> negotiator({compressorName});
mgr.serverNegotiate(negotiator, &negotiatorOut);
checkNegotiationResult(negotiatorOut.done(), {compressorName});
auto swm = mgr.decompressMessage(compressedMsg);
ASSERT_EQ(ErrorCodes::BadValue, swm.getStatus());
}
Message buildMessage() {
const auto data = std::string{"Hello, world!"};
const auto bufferSize = MsgData::MsgDataHeaderSize + data.size();
@ -294,6 +314,52 @@ TEST(ZstdMessageCompressor, Overflow) {
checkOverflow(std::make_unique<ZstdMessageCompressor>());
}
TEST(ZlibMessageCompressor, Mismatch) {
checkOverflow(std::make_unique<ZlibMessageCompressor>());
}
TEST(SnappyMessageCompressor, Undersize) {
std::vector<std::uint8_t> payload = {
0x41, 0x0, 0x0, 0x0, 0xad, 0xde, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xdc,
0x7, 0x0, 0x0, 0xdd, 0x7, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x1, 0x27,
0x0, 0x0, 0x1, 0x1, 0x84, 0xfb, 0x1f, 0x0, 0x0, 0x5, 0x5f, 0x69, 0x64,
0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x48, 0x45, 0x41, 0x50, 0x4c, 0x45, 0x41,
0x4b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
auto buffer = SharedBuffer::allocate(payload.size());
std::copy(payload.begin(), payload.end(), buffer.get());
checkUndersize(Message(buffer), std::make_unique<SnappyMessageCompressor>());
}
TEST(ZlibMessageCompressor, Undersize) {
std::vector<std::uint8_t> payload = {
0x3c, 0x00, 0x00, 0x00, 0xad, 0xde, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x07, 0x00,
0x00, 0xdd, 0x07, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x02, 0x78, 0xda, 0x63, 0x60, 0x00,
0x82, 0xdf, 0xf2, 0x0c, 0x0c, 0xac, 0xf1, 0x99, 0x29, 0x0c, 0x0c, 0x02, 0x40, 0x9e, 0x87,
0xab, 0x63, 0x80, 0x8f, 0xab, 0xa3, 0x37, 0x03, 0x12, 0x00, 0x00, 0x6d, 0x26, 0x04, 0x97};
auto buffer = SharedBuffer::allocate(payload.size());
std::copy(payload.begin(), payload.end(), buffer.get());
checkUndersize(Message(buffer), std::make_unique<ZlibMessageCompressor>());
}
TEST(ZstdMessageCompressor, Undersize) {
std::vector<std::uint8_t> payload = {
0x44, 0x0, 0x0, 0x0, 0xad, 0xde, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xdc, 0x7,
0x0, 0x0, 0xdd, 0x7, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x3, 0x28, 0xb5, 0x2f,
0xfd, 0x20, 0x27, 0x15, 0x1, 0x0, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfb, 0x1f,
0x0, 0x0, 0x5, 0x5f, 0x69, 0x64, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x48, 0x45,
0x41, 0x50, 0x4c, 0x45, 0x41, 0x4b, 0x0, 0x1, 0x0, 0x18, 0xc0, 0x9};
auto buffer = SharedBuffer::allocate(payload.size());
std::copy(payload.begin(), payload.end(), buffer.get());
checkUndersize(Message(buffer), std::make_unique<ZstdMessageCompressor>());
}
TEST(MessageCompressorManager, SERVER_28008) {
// Create a client and server that will negotiate the same compressors,

View File

@ -80,7 +80,7 @@ StatusWith<std::size_t> ZlibMessageCompressor::decompressData(ConstDataRange inp
}
counterHitDecompress(input.length(), output.length());
return {output.length()};
return {length};
}