From 512e75a56195adf65577a024e363b36761cfc897 Mon Sep 17 00:00:00 2001
From: Kai Koehne <kai.koehne@nokia.com>
Date: Fri, 11 Jun 2010 08:46:32 +0200
Subject: [PATCH] QmlDesigner: Fix crash when typing keywords as Ids

We don't check that an ID entered in the Navigator or Property Editor
is not a JavaScript keyword. This patch revamps the RewritingException
that happens in this case in a InvalidIdException.

Task-number: QTCREATORBUG-1540
---
 .../exceptions/invalididexception.cpp         | 38 ++++++++++---------
 .../designercore/include/invalididexception.h | 16 +++++---
 .../qmldesigner/designercore/model/model.cpp  |  8 +++-
 .../designercore/model/modelnode.cpp          |  4 +-
 4 files changed, 39 insertions(+), 27 deletions(-)

diff --git a/src/plugins/qmldesigner/designercore/exceptions/invalididexception.cpp b/src/plugins/qmldesigner/designercore/exceptions/invalididexception.cpp
index b56c2f0dc39..39b7c983520 100644
--- a/src/plugins/qmldesigner/designercore/exceptions/invalididexception.cpp
+++ b/src/plugins/qmldesigner/designercore/exceptions/invalididexception.cpp
@@ -36,34 +36,36 @@ InvalidIdException::InvalidIdException(int line,
                                        const QString &function,
                                        const QString &file,
                                        const QString &id,
-                                       bool duplicate) :
-    InvalidArgumentException(line, function, file, "id"), m_id(id), m_duplicate(duplicate)
+                                       Reason reason) :
+    InvalidArgumentException(line, function, file, "id"),
+    m_id(id)
 {
+    if (reason == InvalidCharacters) {
+        m_description = QCoreApplication::translate("InvalidIdException", "Only alphanumeric characters and underscore allowed.\nIds must begin with a lowercase letter.");
+    } else {
+        m_description = QCoreApplication::translate("InvalidIdException", "Ids have to be unique.");
+    }
 }
 
-QString InvalidIdException::type() const
-{
-    return "InvalidIdException";
-}
-
-QString InvalidIdException::description() const
+InvalidIdException::InvalidIdException(int line,
+                                       const QString &function,
+                                       const QString &file,
+                                       const QString &id,
+                                       const QString &description) :
+    InvalidArgumentException(line, function, file, "id"),
+    m_id(id),
+    m_description(description)
 {
-    if (m_duplicate)
-        return duplicateErrorMessage(m_id);
-
-    return invalidErrorMessage(m_id);
 }
 
-QString InvalidIdException::duplicateErrorMessage(const QString &id)
+QString InvalidIdException::type() const
 {
-     return QCoreApplication::translate("InvalidIdException", "Ids have to be unique: ") + id;
+    return "InvalidIdException";
 }
 
-QString InvalidIdException::invalidErrorMessage(const QString &id)
+QString InvalidIdException::description() const
 {
-    return QCoreApplication::translate("InvalidIdException", "Invalid Id: ") + 
-      id + QCoreApplication::translate("InvalidIdException", 
-      "\nOnly alphanumeric characters and underscore allowed.\nIds must begin with a lowercase letter.");
+    return QCoreApplication::translate("InvalidIdException", "Invalid Id: %1\n%2").arg(m_id, m_description);
 }
 
 }
diff --git a/src/plugins/qmldesigner/designercore/include/invalididexception.h b/src/plugins/qmldesigner/designercore/include/invalididexception.h
index f9e367692ff..2431710e07c 100644
--- a/src/plugins/qmldesigner/designercore/include/invalididexception.h
+++ b/src/plugins/qmldesigner/designercore/include/invalididexception.h
@@ -37,22 +37,26 @@ namespace QmlDesigner {
 class CORESHARED_EXPORT InvalidIdException : public InvalidArgumentException
 {
 public:
+    enum Reason { InvalidCharacters, DuplicateId };
+
+    InvalidIdException(int line,
+                       const QString &function,
+                       const QString &file,
+                       const QString &id,
+                       Reason reason);
+
     InvalidIdException(int line,
                        const QString &function,
                        const QString &file,
                        const QString &id,
-                       bool duplicate = false);
+                       const QString &description);
 
     QString type() const;
     QString description() const;
 
-    static QString duplicateErrorMessage(const QString &id);
-    static QString invalidErrorMessage(const QString &id);
-
 private:
     QString m_id;
-    bool m_duplicate;
-
+    QString m_description;
 };
 
 }
diff --git a/src/plugins/qmldesigner/designercore/model/model.cpp b/src/plugins/qmldesigner/designercore/model/model.cpp
index 7c0bc1d90f2..dc66a9c9705 100644
--- a/src/plugins/qmldesigner/designercore/model/model.cpp
+++ b/src/plugins/qmldesigner/designercore/model/model.cpp
@@ -65,6 +65,7 @@
 #include "rewritertransaction.h"
 #include "rewriterview.h"
 #include "rewritingexception.h"
+#include "invalididexception.h"
 
 /*!
 \defgroup CoreModel
@@ -259,7 +260,12 @@ void ModelPrivate::changeNodeId(const InternalNode::Pointer& internalNodePointer
         m_idNodeHash.remove(oldId);
     if (!id.isEmpty())
         m_idNodeHash.insert(id, internalNodePointer);
-    notifyNodeIdChanged(internalNodePointer, id, oldId);
+
+    try {
+        notifyNodeIdChanged(internalNodePointer, id, oldId);
+    } catch (RewritingException &e) {
+        throw InvalidIdException(__LINE__, __FUNCTION__, __FILE__, id, e.description());
+    }
 }
 
 void ModelPrivate::checkPropertyName(const QString &propertyName)
diff --git a/src/plugins/qmldesigner/designercore/model/modelnode.cpp b/src/plugins/qmldesigner/designercore/model/modelnode.cpp
index 722f93777f3..042049b4f9e 100644
--- a/src/plugins/qmldesigner/designercore/model/modelnode.cpp
+++ b/src/plugins/qmldesigner/designercore/model/modelnode.cpp
@@ -180,13 +180,13 @@ void ModelNode::setId(const QString& id)
     }
 
     if (!isValidId(id))
-        throw InvalidIdException(__LINE__, __FUNCTION__, __FILE__, id);
+        throw InvalidIdException(__LINE__, __FUNCTION__, __FILE__, id, InvalidIdException::InvalidCharacters);
 
     if (id == ModelNode::id())
         return;
 
     if (view()->hasId(id))
-        throw InvalidIdException(__LINE__, __FUNCTION__, __FILE__, id, true);
+        throw InvalidIdException(__LINE__, __FUNCTION__, __FILE__, id, InvalidIdException::DuplicateId);
 
     m_model.data()->m_d->changeNodeId(internalNode(), id);
 }
-- 
GitLab