diff --git a/etc/ubsan.denylist b/etc/ubsan.denylist index d944e11c464..99a7d50050e 100644 --- a/etc/ubsan.denylist +++ b/etc/ubsan.denylist @@ -15,7 +15,6 @@ src:src/third_party/immer/dist/immer/detail/hamts/node.hpp # s2 compatibility fun:_ZN8S2CellId14FromFaceIJWrapEiii -src:src/mongo/bson/column/bsoncolumn_helpers.h src:src/third_party/abseil-cpp/dist/absl/numeric/int128_have_intrinsic.inc # SERVER-62972 diff --git a/src/mongo/bson/column/bsoncolumn_helpers.h b/src/mongo/bson/column/bsoncolumn_helpers.h index 4d7146fe09e..8cf89fc6f4f 100644 --- a/src/mongo/bson/column/bsoncolumn_helpers.h +++ b/src/mongo/bson/column/bsoncolumn_helpers.h @@ -44,6 +44,7 @@ #include namespace mongo { + namespace bsoncolumn { /** @@ -551,7 +552,7 @@ public: bsoncolumn::scaleIndexForControlByte(control) == Simple8bTypeUtil::kMemoryAsInteger); - out += simple8b::sum(ptr + 1, size, lastNonRLEBlock); + out = simple8b::add(out, simple8b::sum(ptr + 1, size, lastNonRLEBlock)); ptr += 1 + size; } @@ -576,7 +577,8 @@ public: bsoncolumn::scaleIndexForControlByte(control) == Simple8bTypeUtil::kMemoryAsInteger); - out += simple8b::prefixSum(ptr + 1, size, prefix, lastNonRLEBlock); + out = simple8b::add( + out, simple8b::prefixSum(ptr + 1, size, prefix, lastNonRLEBlock)); ptr += 1 + size; } @@ -603,7 +605,8 @@ public: auto encodedDouble = Simple8bTypeUtil::encodeDouble(last, scaleIndex); uassert(9095626, "Invalid double encoding in BSON Column", encodedDouble); lastValue = *encodedDouble; - lastValue += simple8b::sum(ptr + 1, size, lastNonRLEBlock); + lastValue = + simple8b::add(lastValue, simple8b::sum(ptr + 1, size, lastNonRLEBlock)); last = Simple8bTypeUtil::decodeDouble(lastValue, scaleIndex); @@ -636,7 +639,7 @@ public: bsoncolumn::scaleIndexForControlByte(control) == Simple8bTypeUtil::kMemoryAsInteger); - out += simple8b::sum(ptr + 1, size, lastNonRLEBlock); + out = simple8b::add(out, simple8b::sum(ptr + 1, size, lastNonRLEBlock)); ptr += 1 + size; } diff --git a/src/mongo/bson/column/simple8b.h b/src/mongo/bson/column/simple8b.h index fefeabd53c3..d12fbb4be44 100644 --- a/src/mongo/bson/column/simple8b.h +++ b/src/mongo/bson/column/simple8b.h @@ -399,6 +399,18 @@ T sum(const char* buffer, size_t size, uint64_t& prevNonRLE); */ template T prefixSum(const char* buffer, size_t size, T& prefix, uint64_t& prevNonRLE); + +/** + * Helper that performs signed addition as unsigned to get the defined wrap-around overflow behavior + * rather than overflow, which is undefined behavior. + */ +static constexpr int64_t add(int64_t lhs, int64_t rhs) { + return static_cast(static_cast(lhs) + static_cast(rhs)); +} +static constexpr int128_t add(int128_t lhs, int128_t rhs) { + return static_cast(static_cast(lhs) + static_cast(rhs)); +} + } // namespace simple8b } // namespace mongo diff --git a/src/mongo/bson/column/simple8b.inl b/src/mongo/bson/column/simple8b.inl index dc4baaaef05..87ae27a293b 100644 --- a/src/mongo/bson/column/simple8b.inl +++ b/src/mongo/bson/column/simple8b.inl @@ -37,16 +37,6 @@ namespace { // Sentinel to represent missing, this value is not encodable in simple8b static constexpr int64_t kMissing = std::numeric_limits::max(); -// Performs addition as unsigned and cast back to signed to get overflow defined to wrapped around -// instead of undefined behavior. -static constexpr int64_t add(int64_t lhs, int64_t rhs) { - return static_cast(static_cast(lhs) + static_cast(rhs)); -} - -static constexpr int128_t add(int128_t lhs, int128_t rhs) { - return static_cast(static_cast(lhs) + static_cast(rhs)); -} - // Simple Simple8b decoder for decoding any basic simple8b block where all bits are used for the // value, decodes signed integer at runtime. Suitable for selectors with many bits per slot. Encoded // should be be machine endian and first slot should start at least significant bit.