diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2018-07-09 13:35:57 +0200 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2018-07-10 12:49:50 +0000 |
commit | 41342facfa10a6a69ec6e23e629975cd0263e39e (patch) | |
tree | d23d316a9efcbc2aa7594e95f31709f676eac6f6 /src/designer/src/lib/uilib/abstractformbuilder.cpp | |
parent | a5fffeba866e259f8435ec1c975edb3d80d3632f (diff) |
Qt Designer: Fix Qt Creator crashes on reloading malformed UI files
Extract the functionality to read the DomUI with version check
to QFormBuilderExtra so that the reading can be split into DomUI
and widget creation.
In FormWindow, check the success of the DomUI creation before
modifying Qt Designer's internal state.
Task-number: QTCREATORBUG-20742
Change-Id: I095f80e90966eba67d8994cd68e83c3e11aa0ee9
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
Diffstat (limited to 'src/designer/src/lib/uilib/abstractformbuilder.cpp')
-rw-r--r-- | src/designer/src/lib/uilib/abstractformbuilder.cpp | 87 |
1 files changed, 6 insertions, 81 deletions
diff --git a/src/designer/src/lib/uilib/abstractformbuilder.cpp b/src/designer/src/lib/uilib/abstractformbuilder.cpp index af8b73b0d..f9275b852 100644 --- a/src/designer/src/lib/uilib/abstractformbuilder.cpp +++ b/src/designer/src/lib/uilib/abstractformbuilder.cpp @@ -93,7 +93,7 @@ # include <private/qlayout_p.h> // Compiling within Designer #endif -#include <QtCore/QXmlStreamReader> +#include <QtCore/QXmlStreamWriter> #include <QtCore/qdebug.h> @@ -178,70 +178,6 @@ QAbstractFormBuilder::~QAbstractFormBuilder() { } -// Return UI file version from attribute 'version="4.0"' -static QPair<int, int> uiVersion(const QString &attr) -{ - const QVector<QStringRef> versions = attr.splitRef(QLatin1Char('.'), QString::SkipEmptyParts); - if (versions.size() >= 2) { - bool okMajor, okMinor; - const int majorVersion = versions.at(0).toInt(&okMajor); - const int minorVersion = versions.at(1).toInt(&okMinor); - if (okMajor && okMinor) - return QPair<int, int>(majorVersion, minorVersion); - } - return QPair<int, int>(-1, -1); -} - -static inline QString msgXmlError(const QXmlStreamReader &reader) -{ - return QCoreApplication::translate("QAbstractFormBuilder", "An error has occurred while reading the UI file at line %1, column %2: %3") - .arg(reader.lineNumber()).arg(reader.columnNumber()).arg(reader.errorString()); -} - -// Read and check the version and the (optional) language attribute -// of an <ui> element and leave reader positioned at <ui>. -static bool inline readUiAttributes(QXmlStreamReader &reader, const QString &language, QString *errorMessage) -{ - const QString uiElement = QStringLiteral("ui"); - // Read up to first element - while (!reader.atEnd()) { - switch (reader.readNext()) { - case QXmlStreamReader::Invalid: - *errorMessage = msgXmlError(reader); - return false; - case QXmlStreamReader::StartElement: - if (reader.name().compare(uiElement, Qt::CaseInsensitive) == 0) { - const QString versionAttribute = QStringLiteral("version"); - const QString languageAttribute = QStringLiteral("language"); - const QXmlStreamAttributes attributes = reader.attributes(); - if (attributes.hasAttribute(versionAttribute)) { - const QString versionString = attributes.value(versionAttribute).toString(); - if (uiVersion(versionString).first < 4) { - *errorMessage = QCoreApplication::translate("QAbstractFormBuilder", "This file was created using Designer from Qt-%1 and cannot be read.") - .arg(versionString); - return false; - } // version error - } // has version - if (attributes.hasAttribute(languageAttribute)) { - // Check on optional language (Jambi) - const QString formLanguage = attributes.value(languageAttribute).toString(); - if (!formLanguage.isEmpty() && formLanguage.compare(language, Qt::CaseInsensitive)) { - *errorMessage = QCoreApplication::translate("QAbstractFormBuilder", "This file cannot be read because it was created using %1.").arg(formLanguage); - return false; - } // language error - } // has language - return true; - } // <ui> matched - break; - default: - break; - } - } - // No <ui> found. - *errorMessage = QCoreApplication::translate("QAbstractFormBuilder", "Invalid UI file: The root element <ui> is missing."); - return false; -} - /*! \fn QWidget *QAbstractFormBuilder::load(QIODevice *device, QWidget *parent) @@ -252,23 +188,12 @@ static bool inline readUiAttributes(QXmlStreamReader &reader, const QString &lan */ QWidget *QAbstractFormBuilder::load(QIODevice *dev, QWidget *parentWidget) { - QXmlStreamReader reader(dev); - d->m_errorString.clear(); - if (!readUiAttributes(reader, d->m_language, &d->m_errorString)) { - uiLibWarning(d->m_errorString); - return 0; - } - DomUI ui; - ui.read(reader); - if (reader.hasError()) { - d->m_errorString = msgXmlError(reader); - uiLibWarning(d->m_errorString); - return 0; - } - - QWidget *widget = create(&ui, parentWidget); + QScopedPointer<DomUI> ui(d->readUi(dev)); + if (ui.isNull()) + return nullptr; + QWidget *widget = create(ui.data(), parentWidget); if (!widget && d->m_errorString.isEmpty()) - d->m_errorString = QCoreApplication::translate("QAbstractFormBuilder", "Invalid UI file"); + d->m_errorString = QFormBuilderExtra::msgInvalidUiFile(); return widget; } |