From fc64369f9d8d3279f73b89fdd76df2fa1468ff72 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Fri, 4 Aug 2017 11:39:28 +0700 Subject: [PATCH] Purge history on buffer reload when NoUndo flag is on We were preserving the history in that case, so on fifo buffers (that set the NoUndo flag until the fifo is closed), we still had the history from the "previous life" of the buffer, leading crashes when trying to apply it. Fixes #1518 --- src/buffer.cc | 9 ++++++--- src/buffer.hh | 4 ++-- .../1518-wrong-undo-handling-with-fifo-buffers/cmd | 1 + 3 files changed, 9 insertions(+), 5 deletions(-) create mode 100644 test/regression/1518-wrong-undo-handling-with-fifo-buffers/cmd diff --git a/src/buffer.cc b/src/buffer.cc index b85d01ee..147e1bbf 100644 --- a/src/buffer.cc +++ b/src/buffer.cc @@ -242,10 +242,13 @@ void Buffer::reload(StringView data, timespec fs_timestamp) if (not record_undo) { + // Erase history about to be invalidated history + m_history_cursor = &m_history; + m_last_save_history_cursor = &m_history; + m_history = HistoryNode{m_next_history_id++, nullptr}; + m_changes.push_back({ Change::Erase, {0,0}, line_count() }); - static_cast(m_lines) = std::move(parsed_lines.lines); - m_changes.push_back({ Change::Insert, {0,0}, line_count() }); } else @@ -340,7 +343,7 @@ bool Buffer::redo(size_t count) noexcept while (count-- != 0 and m_history_cursor->redo_child) { - m_history_cursor = m_history_cursor->redo_child.get(); + m_history_cursor = m_history_cursor->redo_child; for (const Modification& modification : m_history_cursor->undo_group) apply_modification(modification); diff --git a/src/buffer.hh b/src/buffer.hh index ee03c0a0..7cf2db7b 100644 --- a/src/buffer.hh +++ b/src/buffer.hh @@ -252,14 +252,14 @@ private: using UndoGroup = Vector; - struct HistoryNode : SafeCountable, UseMemoryDomain + struct HistoryNode : SafeCountable, UseMemoryDomain { HistoryNode(size_t id, HistoryNode* parent); UndoGroup undo_group; Vector, MemoryDomain::BufferMeta> childs; SafePtr parent; - SafePtr redo_child; + HistoryNode* redo_child = nullptr; // not a SafePtr to avoid lifetime issues between this and childs size_t id; TimePoint timepoint; }; diff --git a/test/regression/1518-wrong-undo-handling-with-fifo-buffers/cmd b/test/regression/1518-wrong-undo-handling-with-fifo-buffers/cmd new file mode 100644 index 00000000..a8902d2d --- /dev/null +++ b/test/regression/1518-wrong-undo-handling-with-fifo-buffers/cmd @@ -0,0 +1 @@ +ifoo:edit -fifo /dev/null %u