summaryrefslogtreecommitdiffstats
path: root/src/designer/src/lib/uilib/abstractformbuilder.cpp
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2018-07-09 13:35:57 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2018-07-10 12:49:50 +0000
commit41342facfa10a6a69ec6e23e629975cd0263e39e (patch)
treed23d316a9efcbc2aa7594e95f31709f676eac6f6 /src/designer/src/lib/uilib/abstractformbuilder.cpp
parenta5fffeba866e259f8435ec1c975edb3d80d3632f (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.cpp87
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;
}