From 321a23f1dcf0579f9502d45a0203f2a79af7433b Mon Sep 17 00:00:00 2001 From: Weaselbot Date: Wed, 22 Jul 2026 18:48:46 -0400 Subject: [PATCH] Avoid reading uninitialized end.p for point writes/reads For point writes and point reads (end.len == 0), end.p is not part of the API contract and callers may leave it uninitialized -- both the C and C++ API smoke tests and the fuzz test driver do so. However, insertPointWritesOrSorted and check::Job::init unconditionally built a TrivialSpan from end.p, reading the uninitialized pointer even though it is never used for point operations. Move the end span construction into the range-write/range-read branches so end.p is only read when end.len > 0. This is semantically identical but removes the uninitialized reads that MemorySanitizer reports. --- ConflictSet.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/ConflictSet.cpp b/ConflictSet.cpp index 200a592..58049c5 100644 --- a/ConflictSet.cpp +++ b/ConflictSet.cpp @@ -3864,11 +3864,10 @@ PRESERVE_NONE void right_side_iter(Job *job, Context *context) { void Job::init(const ConflictSet::ReadRange *read, ConflictSet::Result *result, Node *root, int64_t oldestVersionFullPrecision) { auto begin = TrivialSpan(read->begin.p, read->begin.len); - auto end = TrivialSpan(read->end.p, read->end.len); if (read->readVersion < oldestVersionFullPrecision) [[unlikely]] { *result = ConflictSet::TooOld; continuation = complete; - } else if (end.size() == 0) { + } else if (read->end.len == 0) { this->begin = begin; this->n = root; this->readVersion = InternalVersionT(read->readVersion); @@ -3876,7 +3875,7 @@ void Job::init(const ConflictSet::ReadRange *read, ConflictSet::Result *result, continuation = check::point_read_state_machine::begin; } else { this->begin = begin; - this->end = end; + this->end = TrivialSpan(read->end.p, read->end.len); this->n = root; this->readVersion = InternalVersionT(read->readVersion); this->result = result; @@ -5046,8 +5045,8 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl { for (int i = 0; i < count; ++i) { const auto &w = writes[i]; auto begin = TrivialSpan(w.begin.p, w.begin.len); - auto end = TrivialSpan(w.end.p, w.end.len); if (w.end.len > 0) { + auto end = TrivialSpan(w.end.p, w.end.len); addWriteRange(rootParent->children[0], begin, end, InternalVersionT(writeVersion), &writeContext); } else {