Avoid signed overflow
CI / pre-commit (push) Successful in 2m8s
CI / test (arm64, -DCMAKE_BUILD_TYPE=Debug -DMSAN_TOOLCHAIN_PATH=/opt/msan, 22, https://minio.weaselab.dev/public/aarch64/msan-toolchain-22.1.8.tar.zst, debug-arm64, ubuntu-latest-arm64) (push) Successful in 3m57s
CI / test (amd64, -DCMAKE_BUILD_TYPE=Debug -DMSAN_TOOLCHAIN_PATH=/opt/msan, 21, https://minio.weaselab.dev/public/x86_64/msan-toolchain-21.1.8.tar.zst, debug, ubuntu-latest-amd64) (push) Successful in 4m14s
CI / release (arm64, , ubuntu-latest-arm64) (push) Successful in 3m29s
CI / test (amd64, -DCMAKE_CXX_FLAGS=-DUSE_64_BIT=1, 21, , 64-bit-versions, ubuntu-latest-amd64) (push) Successful in 3m28s
CI / test (amd64, -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++, 21, , gcc, ubuntu-latest-amd64) (push) Successful in 3m22s
CI / test (amd64, -DUSE_SIMD_FALLBACK=ON, 21, , simd-fallback, ubuntu-latest-amd64) (push) Successful in 3m27s
CI / release (amd64, -DMSAN_TOOLCHAIN_PATH=/opt/msan, ubuntu-latest-amd64) (push) Successful in 5m46s
CI / coverage (push) Successful in 4m12s
CI / pre-commit (push) Successful in 2m8s
CI / test (arm64, -DCMAKE_BUILD_TYPE=Debug -DMSAN_TOOLCHAIN_PATH=/opt/msan, 22, https://minio.weaselab.dev/public/aarch64/msan-toolchain-22.1.8.tar.zst, debug-arm64, ubuntu-latest-arm64) (push) Successful in 3m57s
CI / test (amd64, -DCMAKE_BUILD_TYPE=Debug -DMSAN_TOOLCHAIN_PATH=/opt/msan, 21, https://minio.weaselab.dev/public/x86_64/msan-toolchain-21.1.8.tar.zst, debug, ubuntu-latest-amd64) (push) Successful in 4m14s
CI / release (arm64, , ubuntu-latest-arm64) (push) Successful in 3m29s
CI / test (amd64, -DCMAKE_CXX_FLAGS=-DUSE_64_BIT=1, 21, , 64-bit-versions, ubuntu-latest-amd64) (push) Successful in 3m28s
CI / test (amd64, -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++, 21, , gcc, ubuntu-latest-amd64) (push) Successful in 3m22s
CI / test (amd64, -DUSE_SIMD_FALLBACK=ON, 21, , simd-fallback, ubuntu-latest-amd64) (push) Successful in 3m27s
CI / release (amd64, -DMSAN_TOOLCHAIN_PATH=/opt/msan, ubuntu-latest-amd64) (push) Successful in 5m46s
CI / coverage (push) Successful in 4m12s
This only happens at implausibly high version numbers, but the fix is straightforward so we'll just do it anyway. Closes #84
This commit is contained in:
+1
-1
@@ -5091,7 +5091,7 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
|
||||
|
||||
if (oldestExtantVersion < writeVersion - kMaxCorrectVersionWindow)
|
||||
[[unlikely]] {
|
||||
if (writeVersion > newestVersionFullPrecision + kNominalVersionWindow) {
|
||||
if (writeVersion - kNominalVersionWindow > newestVersionFullPrecision) {
|
||||
eraseTree(rootParent->children[0], &writeContext);
|
||||
init(writeVersion - kNominalVersionWindow);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#include <limits>
|
||||
|
||||
using namespace weaselab;
|
||||
|
||||
@@ -23,6 +24,28 @@ int main(void) {
|
||||
int64_t bytes = cs.getBytes();
|
||||
assert(bytes > 0);
|
||||
|
||||
// Regression: a write just below INT64_MAX must not overflow the nominal
|
||||
// version window comparison and erase entries that reads still observe.
|
||||
// Versions are only required to be >= 0, so this is valid input.
|
||||
{
|
||||
const int64_t imax = std::numeric_limits<int64_t>::max();
|
||||
const int64_t v0 = imax - int64_t(1000000000);
|
||||
ConflictSet nearMax(0);
|
||||
ConflictSet::WriteRange w2;
|
||||
w2.begin.p = (const uint8_t *)"key";
|
||||
w2.begin.len = 3;
|
||||
w2.end.len = 0;
|
||||
nearMax.addWrites(&w2, 1, v0);
|
||||
nearMax.addWrites(&w2, 0, imax);
|
||||
ConflictSet::ReadRange r2;
|
||||
r2.begin.p = (const uint8_t *)"key";
|
||||
r2.begin.len = 3;
|
||||
r2.end.len = 0;
|
||||
r2.readVersion = v0 - 1;
|
||||
nearMax.check(&r2, &result, 1);
|
||||
assert(result == ConflictSet::Conflict);
|
||||
}
|
||||
|
||||
ConflictSet::MetricsV1 *metrics;
|
||||
int metricsCount;
|
||||
cs.getMetricsV1(&metrics, &metricsCount);
|
||||
|
||||
Reference in New Issue
Block a user