summaryrefslogtreecommitdiffstats
path: root/source/kde/kde/patch/ktexteditor/686da7797105a93035cfbc7edbf2a8e8f8adf0ec.patch
blob: 7fca1a9e5e09e32739c5a4af60d61f2f76fa3cab (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
From 686da7797105a93035cfbc7edbf2a8e8f8adf0ec Mon Sep 17 00:00:00 2001
From: Christoph Cullmann <cullmann@kde.org>
Date: Wed, 17 Feb 2021 20:51:12 +0100
Subject: [PATCH] ensure rangesForLine caching is correcly updated

during fixing a segfault, as invalid range pointer were kept
in the rangesForLine cache, too many ranges were purged

properly update the cache before potential invalidation

add unit test to avoid regressions in the future
---
 autotests/src/movingrange_test.cpp | 33 ++++++++++++++++++++++++++++++
 autotests/src/movingrange_test.h   |  1 +
 src/buffer/katetextblock.cpp       | 10 +++++++++
 3 files changed, 44 insertions(+)

diff --git a/autotests/src/movingrange_test.cpp b/autotests/src/movingrange_test.cpp
index 66393ae7..81a85b1a 100644
--- a/autotests/src/movingrange_test.cpp
+++ b/autotests/src/movingrange_test.cpp
@@ -459,3 +459,36 @@ void MovingRangeTest::testLineRemoved()
     auto r = doc.buffer().rangesForLine(1, view, true);
     QVERIFY(r.isEmpty());
 }
+
+void MovingRangeTest::testLineWrapOrUnwrapUpdateRangeForLineCache()
+{
+    KTextEditor::DocumentPrivate doc;
+    doc.setText(
+        QStringLiteral("abcd\n"
+                       "efgh\n"
+                       "hijk\n"));
+
+    // add range to line 2, it shall be in rangeForLine for the right lines after each update!
+    // must be single line range to be in the cache!
+    auto range = static_cast<Kate::TextRange *>(doc.newMovingRange({2, 1, 2, 3},
+                                                                   KTextEditor::MovingRange::ExpandLeft | KTextEditor::MovingRange::ExpandRight,
+                                                                   KTextEditor::MovingRange::InvalidateIfEmpty));
+
+    // range shall be in the lookup cache for line 2
+    QVERIFY(doc.buffer().rangesForLine(0, nullptr, false).isEmpty());
+    QVERIFY(doc.buffer().rangesForLine(1, nullptr, false).isEmpty());
+    QVERIFY(doc.buffer().rangesForLine(2, nullptr, false).contains(range));
+
+    // wrap line 1 => range should move to line 3
+    doc.editWrapLine(1, 1);
+    QVERIFY(doc.buffer().rangesForLine(0, nullptr, false).isEmpty());
+    QVERIFY(doc.buffer().rangesForLine(1, nullptr, false).isEmpty());
+    QVERIFY(doc.buffer().rangesForLine(2, nullptr, false).isEmpty());
+    QVERIFY(doc.buffer().rangesForLine(3, nullptr, false).contains(range));
+
+    // unwrap line 1 => range should back move to line 2
+    doc.editUnWrapLine(1);
+    QVERIFY(doc.buffer().rangesForLine(0, nullptr, false).isEmpty());
+    QVERIFY(doc.buffer().rangesForLine(1, nullptr, false).isEmpty());
+    QVERIFY(doc.buffer().rangesForLine(2, nullptr, false).contains(range));
+}
diff --git a/autotests/src/movingrange_test.h b/autotests/src/movingrange_test.h
index 6f8c057d..016655f7 100644
--- a/autotests/src/movingrange_test.h
+++ b/autotests/src/movingrange_test.h
@@ -24,6 +24,7 @@ private Q_SLOTS:
     void testFeedbackCaret();
     void testFeedbackMouse();
     void testLineRemoved();
+    void testLineWrapOrUnwrapUpdateRangeForLineCache();
 };
 
 #endif // KATE_MOVINGRANGE_TEST_H
diff --git a/src/buffer/katetextblock.cpp b/src/buffer/katetextblock.cpp
index 43d137e4..246897b4 100644
--- a/src/buffer/katetextblock.cpp
+++ b/src/buffer/katetextblock.cpp
@@ -167,6 +167,11 @@ void TextBlock::wrapLine(const KTextEditor::Cursor &position, int fixStartLinesS
     // we might need to invalidate ranges or notify about their changes
     // checkValidity might trigger delete of the range!
     for (TextRange *range : qAsConst(changedRanges)) {
+        // we need to do updateRange to ALWAYS ensure the line => range and back cache is updated
+        // see MovingRangeTest::testLineWrapOrUnwrapUpdateRangeForLineCache
+        updateRange(range);
+
+        // in addition: ensure that we really invalidate bad ranges!
         range->checkValidity(range->toLineRange());
     }
 }
@@ -333,6 +338,11 @@ void TextBlock::unwrapLine(int line, TextBlock *previousBlock, int fixStartLines
     // we might need to invalidate ranges or notify about their changes
     // checkValidity might trigger delete of the range!
     for (TextRange *range : qAsConst(changedRanges)) {
+        // we need to do updateRange to ALWAYS ensure the line => range and back cache is updated
+        // see MovingRangeTest::testLineWrapOrUnwrapUpdateRangeForLineCache
+        updateRange(range);
+
+        // in addition: ensure that we really invalidate bad ranges!
         range->checkValidity(range->toLineRange());
     }
 }
-- 
GitLab