aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhluk <hluk@email.cz>2013-12-01 15:09:04 +0100
committerhjk <hjk121@nokiamail.com>2013-12-03 11:40:51 +0100
commitb1a714ed44501dd972b7f16e9a0321694832514a (patch)
treeb1224b1ebcc46ff2d344a613d5fb20bd6abc0d1f
parent4fd4f5d9fcc4b6ea8b1d554fe013a994ef46b3ce (diff)
FakeVim: Fix infinite loop when replacing empty text
Change-Id: Ie4ba6420889b0a6a5712b43a11f8366aa9a30edc Reviewed-by: Eike Ziller <eike.ziller@digia.com> Reviewed-by: hjk <hjk121@nokiamail.com>
-rw-r--r--src/plugins/fakevim/fakevim_test.cpp11
-rw-r--r--src/plugins/fakevim/fakevimhandler.cpp14
2 files changed, 24 insertions, 1 deletions
diff --git a/src/plugins/fakevim/fakevim_test.cpp b/src/plugins/fakevim/fakevim_test.cpp
index 6b9144da5d..c87685e1ea 100644
--- a/src/plugins/fakevim/fakevim_test.cpp
+++ b/src/plugins/fakevim/fakevim_test.cpp
@@ -2206,6 +2206,17 @@ void FakeVimPlugin::test_vim_substitute()
COMMAND("'<,'>s/^/*", "abc" N "**def" N X "**ghi" N "jkl");
KEYS("u", "abc" N X "*def" N "*ghi" N "jkl");
KEYS("gv:s/^/+<CR>", "abc" N "+*def" N X "+*ghi" N "jkl");
+
+ // replace empty string
+ data.setText("abc");
+ COMMAND("s//--/g", "--a--b--c");
+
+ // remove characters
+ data.setText("abc def");
+ COMMAND("s/[abde]//g", "c f");
+ COMMAND("undo | s/[bcef]//g", "a d");
+ COMMAND("undo | s/\\w//g", " ");
+ COMMAND("undo | s/f\\|$/-/g", "abc de-");
}
void FakeVimPlugin::test_vim_ex_yank()
diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp
index 7460bb1de7..ed6513da0a 100644
--- a/src/plugins/fakevim/fakevimhandler.cpp
+++ b/src/plugins/fakevim/fakevimhandler.cpp
@@ -623,10 +623,22 @@ static bool substituteText(QString *text, QRegExp &pattern, const QString &repla
{
bool substituted = false;
int pos = 0;
+ int right = -1;
while (true) {
pos = pattern.indexIn(*text, pos, QRegExp::CaretAtZero);
if (pos == -1)
break;
+
+ // ensure that substitution is advancing towards end of line
+ if (right == text->size() - pos) {
+ ++pos;
+ if (pos == text->size())
+ break;
+ continue;
+ }
+
+ right = text->size() - pos;
+
substituted = true;
QString matched = text->mid(pos, pattern.cap(0).size());
QString repl;
@@ -652,7 +664,7 @@ static bool substituteText(QString *text, QRegExp &pattern, const QString &repla
}
}
text->replace(pos, matched.size(), repl);
- pos += qMax(1, repl.size());
+ pos += (repl.isEmpty() && matched.isEmpty()) ? 1 : repl.size();
if (pos >= text->size() || !global)
break;