From 6ce9a80afa43b3a40b0244ebef3b41ba03cc76a0 Mon Sep 17 00:00:00 2001
From: Erik Verbruggen <erik.verbruggen@digia.com>
Date: Thu, 10 Jan 2013 16:41:14 +0100
Subject: [PATCH] C++: fix invalid common prefix calculation.

This was the indirect cause for "random" freezes when using
code-completion. The direct cause was a while loop counting down to 0,
but starting with a negative value. Both are fixed now.

Task-number: QTCREATORBUG-8472
Task-number: QTCREATORBUG-8532
Change-Id: I782a46be3ac8282d7484d0bf0c6fd30be6b171c8
Reviewed-by: Christian Kandeler <christian.kandeler@digia.com>
Reviewed-by: Kai Koehne <kai.koehne@digia.com>
---
 src/plugins/cpptools/cppcompletionassist.cpp  |  2 +-
 .../codeassist/basicproposalitemlistmodel.cpp | 27 +++++++++++--------
 2 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/src/plugins/cpptools/cppcompletionassist.cpp b/src/plugins/cpptools/cppcompletionassist.cpp
index 8dd911aac85..f3a6a08f9e3 100644
--- a/src/plugins/cpptools/cppcompletionassist.cpp
+++ b/src/plugins/cpptools/cppcompletionassist.cpp
@@ -344,7 +344,7 @@ void CppAssistProposalItem::applyContextualContent(TextEditor::BaseTextEditor *e
     if (!inEditor.isEmpty()) {
         preserveLength = toInsert.length() - (editor->position() - basePosition);
         const int inEditorLength = inEditor.length();
-        while (preserveLength) {
+        while (preserveLength > 0) {
             if (inEditor.startsWith(toInsert.right(preserveLength))
                     && (inEditorLength == preserveLength
                         || (!inEditor.at(preserveLength).isLetterOrNumber()
diff --git a/src/plugins/texteditor/codeassist/basicproposalitemlistmodel.cpp b/src/plugins/texteditor/codeassist/basicproposalitemlistmodel.cpp
index 9a488dfaa6f..84657911c79 100644
--- a/src/plugins/texteditor/codeassist/basicproposalitemlistmodel.cpp
+++ b/src/plugins/texteditor/codeassist/basicproposalitemlistmodel.cpp
@@ -271,22 +271,27 @@ bool BasicProposalItemListModel::keepPerfectMatch(AssistReason reason) const
 
 QString BasicProposalItemListModel::proposalPrefix() const
 {
-    if (m_currentItems.size() >= kMaxPrefixFilter)
+    if (m_currentItems.size() >= kMaxPrefixFilter || m_currentItems.isEmpty())
         return QString();
 
     // Compute common prefix
-    QString firstKey = m_currentItems.first()->text();
-    QString lastKey = m_currentItems.last()->text();
-    const int length = qMin(firstKey.length(), lastKey.length());
-    firstKey.truncate(length);
-    lastKey.truncate(length);
-
-    while (firstKey != lastKey) {
-        firstKey.chop(1);
-        lastKey.chop(1);
+    QString commonPrefix = m_currentItems.first()->text();
+    for (int i = 1, ei = m_currentItems.size(); i < ei; ++i) {
+        QString nextItem = m_currentItems.at(i)->text();
+        const int length = qMin(commonPrefix.length(), nextItem.length());
+        commonPrefix.truncate(length);
+        nextItem.truncate(length);
+
+        while (commonPrefix != nextItem) {
+            commonPrefix.chop(1);
+            nextItem.chop(1);
+        }
+
+        if (commonPrefix.isEmpty()) // there is no common prefix, so return.
+            return commonPrefix;
     }
 
-    return firstKey;
+    return commonPrefix;
 }
 
 IAssistProposalItem *BasicProposalItemListModel::proposalItem(int index) const
-- 
GitLab