From 0f2cc41ed18ca9d13dd1e46a1c17f7912d5d8dc7 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 24 Sep 2026 03:16:59 +0000 Subject: [PATCH] PieceTable: invalidate line index on assignment and merged appends Copy/move assignment kept the destination's line index, so closing a buffer (vector erase move-assigns later buffers down) left the shifted buffer with its predecessor's line offsets and out-of-bounds line views. Appends that merged into an existing piece also skipped invalidation. Audit findings M1, B12. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_015rcVQiiWyTzoNrsvLSaAfB --- PieceTable.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/PieceTable.cc b/PieceTable.cc index 7e271b6..c116d3a 100644 --- a/PieceTable.cc +++ b/PieceTable.cc @@ -58,6 +58,7 @@ PieceTable::operator=(const PieceTable &other) version_ = other.version_; range_cache_ = {}; find_cache_ = {}; + InvalidateLineIndex(); return *this; } @@ -94,6 +95,7 @@ PieceTable::operator=(PieceTable &&other) noexcept version_ = other.version_; range_cache_ = {}; find_cache_ = {}; + InvalidateLineIndex(); return *this; } @@ -221,6 +223,7 @@ PieceTable::addPieceBack(const Source src, const std::size_t start, const std::s last.len += len; total_size_ += len; dirty_ = true; + InvalidateLineIndex(); version_++; range_cache_ = {}; find_cache_ = {}; @@ -254,6 +257,7 @@ PieceTable::addPieceFront(Source src, std::size_t start, std::size_t len) first.len += len; total_size_ += len; dirty_ = true; + InvalidateLineIndex(); version_++; range_cache_ = {}; find_cache_ = {};