From 6060c7444bf63e66a2a88e44815c872f21da3bcf Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 17 May 2020 22:24:52 +0200 Subject: [PATCH] LibGUI: Fix crash in TextDocument::remove(TextRange) Oops, we can't be appending substrings of a string we just deleted! Fix this by building up the new line instead of trying to clear and append in place. This works out nicely as we now do fewer document view updates when removing a range. :^) --- Libraries/LibGUI/TextDocument.cpp | 15 ++++++++++++--- Libraries/LibGUI/TextDocument.h | 1 + 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/Libraries/LibGUI/TextDocument.cpp b/Libraries/LibGUI/TextDocument.cpp index 32ba3a423554ac304901488b1b82fdac71aab4a1..b6d4ef3472759bfd34f588bf5b0a62391d3c2837 100644 --- a/Libraries/LibGUI/TextDocument.cpp +++ b/Libraries/LibGUI/TextDocument.cpp @@ -117,6 +117,12 @@ void TextDocumentLine::clear(TextDocument& document) document.update_views({}); } +void TextDocumentLine::set_text(TextDocument& document, const Vector text) +{ + m_text = move(text); + document.update_views({}); +} + void TextDocumentLine::set_text(TextDocument& document, const StringView& text) { if (text.is_empty()) { @@ -132,6 +138,8 @@ void TextDocumentLine::set_text(TextDocument& document, const StringView& text) void TextDocumentLine::append(TextDocument& document, const u32* codepoints, size_t length) { + if (length == 0) + return; m_text.append(codepoints, length); document.update_views({}); } @@ -588,9 +596,10 @@ void TextDocument::remove(const TextRange& unnormalized_range) ASSERT(range.start().line() == range.end().line() - 1); auto& first_line = line(range.start().line()); auto& second_line = line(range.end().line()); - first_line.clear(*this); - first_line.append(*this, first_line.codepoints(), range.start().column()); - first_line.append(*this, second_line.codepoints() + range.end().column(), second_line.length() - range.end().column()); + Vector codepoints; + codepoints.append(first_line.codepoints(), range.start().column()); + codepoints.append(second_line.codepoints() + range.end().column(), second_line.length() - range.end().column()); + first_line.set_text(*this, move(codepoints)); remove_line(range.end().line()); } diff --git a/Libraries/LibGUI/TextDocument.h b/Libraries/LibGUI/TextDocument.h index 53aed50f4d5334ddcb6909eb155a3d6f0ab4d135..07a858624af4af9a7cfcf8a6b7042491f88a6b28 100644 --- a/Libraries/LibGUI/TextDocument.h +++ b/Libraries/LibGUI/TextDocument.h @@ -160,6 +160,7 @@ public: const u32* codepoints() const { return m_text.data(); } size_t length() const { return m_text.size(); } void set_text(TextDocument&, const StringView&); + void set_text(TextDocument&, Vector); void append(TextDocument&, u32); void prepend(TextDocument&, u32); void insert(TextDocument&, size_t index, u32);