diff options
-rw-r--r-- | src/dbus/qdbusdemarshaller.cpp | 24 | ||||
-rw-r--r-- | tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp | 82 | ||||
-rw-r--r-- | tools/linguist/linguist/messageeditor.cpp | 12 | ||||
-rw-r--r-- | tools/linguist/linguist/messageeditor.h | 2 | ||||
-rw-r--r-- | tools/linguist/linguist/messageeditorwidgets.cpp | 9 | ||||
-rw-r--r-- | tools/linguist/linguist/messageeditorwidgets.h | 5 | ||||
-rw-r--r-- | tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp | 4 |
7 files changed, 125 insertions, 13 deletions
diff --git a/src/dbus/qdbusdemarshaller.cpp b/src/dbus/qdbusdemarshaller.cpp index d9bb5b5..4103552 100644 --- a/src/dbus/qdbusdemarshaller.cpp +++ b/src/dbus/qdbusdemarshaller.cpp @@ -48,10 +48,28 @@ QT_BEGIN_NAMESPACE template <typename T> static inline T qIterGet(DBusMessageIter *it) { - T t; - q_dbus_message_iter_get_basic(it, &t); + // Use a union of expected and largest type q_dbus_message_iter_get_basic + // will return to ensure reading the wrong basic type does not result in + // stack overwrite + union { + // The value to be extracted + T t; + // Largest type that q_dbus_message_iter_get_basic will return + // according to dbus_message_iter_get_basic API documentation + dbus_uint64_t maxValue; + // A pointer to ensure no stack overwrite in case there is a platform + // where sizeof(void*) > sizeof(dbus_uint64_t) + void* ptr; + } value; + + // Initialize the value in case a narrower type is extracted to it. + // Note that the result of extracting a narrower type in place of a wider + // one and vice-versa will be platform-dependent. + value.t = T(); + + q_dbus_message_iter_get_basic(it, &value); q_dbus_message_iter_next(it); - return t; + return value.t; } QDBusDemarshaller::~QDBusDemarshaller() diff --git a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp index cca212e..9754a84 100644 --- a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp +++ b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp @@ -93,6 +93,9 @@ private slots: void receiveUnknownType_data(); void receiveUnknownType(); + void demarshallPrimitives_data(); + void demarshallPrimitives(); + private: int fileDescriptorForTest(); @@ -1168,5 +1171,84 @@ void tst_QDBusMarshall::receiveUnknownType() #endif } +void tst_QDBusMarshall::demarshallPrimitives_data() +{ + sendBasic_data(); +} + +template<class T> +QVariant demarshallPrimitiveAs(const QDBusArgument& dbusArg) +{ + T val; + dbusArg >> val; + return qVariantFromValue(val); +} + +QVariant demarshallPrimitiveAs(int typeIndex, const QDBusArgument& dbusArg) +{ + switch (typeIndex) { + case 0: + return demarshallPrimitiveAs<uchar>(dbusArg); + case 1: + return demarshallPrimitiveAs<bool>(dbusArg); + case 2: + return demarshallPrimitiveAs<short>(dbusArg); + case 3: + return demarshallPrimitiveAs<ushort>(dbusArg); + case 4: + return demarshallPrimitiveAs<int>(dbusArg); + case 5: + return demarshallPrimitiveAs<uint>(dbusArg); + case 6: + return demarshallPrimitiveAs<qlonglong>(dbusArg); + case 7: + return demarshallPrimitiveAs<qulonglong>(dbusArg); + case 8: + return demarshallPrimitiveAs<double>(dbusArg); + default: + return QVariant(); + } +} + +void tst_QDBusMarshall::demarshallPrimitives() +{ + QFETCH(QVariant, value); + QFETCH(QString, sig); + + QDBusConnection con = QDBusConnection::sessionBus(); + + QVERIFY(con.isConnected()); + + // Demarshall each test data value to all primitive types to test + // demarshalling to the wrong type does not cause a crash + for (int typeIndex = 0; true; ++typeIndex) { + QDBusMessage msg = QDBusMessage::createMethodCall(serviceName, objectPath, + interfaceName, "ping"); + QDBusArgument sendArg; + sendArg.beginStructure(); + sendArg.appendVariant(value); + sendArg.endStructure(); + msg.setArguments(QVariantList() << qVariantFromValue(sendArg)); + QDBusMessage reply = con.call(msg); + + const QDBusArgument receiveArg = qvariant_cast<QDBusArgument>(reply.arguments().at(0)); + receiveArg.beginStructure(); + QCOMPARE(receiveArg.currentSignature(), sig); + + const QVariant receiveValue = demarshallPrimitiveAs(typeIndex, receiveArg); + if (receiveValue.type() == value.type()) { + // Value type is the same, compare the values + QCOMPARE(receiveValue, value); + QVERIFY(receiveArg.atEnd()); + } + + receiveArg.endStructure(); + QVERIFY(receiveArg.atEnd()); + + if (!receiveValue.isValid()) + break; + } +} + QTEST_MAIN(tst_QDBusMarshall) #include "tst_qdbusmarshall.moc" diff --git a/tools/linguist/linguist/messageeditor.cpp b/tools/linguist/linguist/messageeditor.cpp index 87c2f4a..2888290 100644 --- a/tools/linguist/linguist/messageeditor.cpp +++ b/tools/linguist/linguist/messageeditor.cpp @@ -262,7 +262,6 @@ void MessageEditor::addPluralForm(int model, const QString &label, bool writable { FormMultiWidget *transEditor = new FormMultiWidget(label); connect(transEditor, SIGNAL(editorCreated(QTextEdit*)), SLOT(editorCreated(QTextEdit*))); - connect(transEditor, SIGNAL(editorDeleted(QTextEdit*)), SLOT(editorDeleted(QTextEdit*))); transEditor->setEditingEnabled(writable); transEditor->setHideWhenEmpty(!writable); if (!m_editors[model].transTexts.isEmpty()) @@ -299,9 +298,9 @@ void MessageEditor::editorCreated(QTextEdit *te) } } -void MessageEditor::editorDeleted(QTextEdit *te) +void MessageEditor::editorDestroyed() { - if (m_selectionHolder == te) + if (m_selectionHolder == sender()) resetSelection(); } @@ -352,9 +351,13 @@ static void clearSelection(QTextEdit *t) void MessageEditor::selectionChanged(QTextEdit *te) { if (te != m_selectionHolder) { - if (m_selectionHolder) + if (m_selectionHolder) { clearSelection(m_selectionHolder); + disconnect(this, SLOT(editorDestroyed())); + } m_selectionHolder = (te->textCursor().hasSelection() ? te : 0); + if (FormatTextEdit *fte = qobject_cast<FormatTextEdit*>(m_selectionHolder)) + connect(fte, SIGNAL(editorDestroyed()), SLOT(editorDestroyed())); updateCanCutCopy(); } } @@ -371,6 +374,7 @@ void MessageEditor::resetSelection() { if (m_selectionHolder) { clearSelection(m_selectionHolder); + disconnect(this, SLOT(editorDestroyed())); m_selectionHolder = 0; updateCanCutCopy(); } diff --git a/tools/linguist/linguist/messageeditor.h b/tools/linguist/linguist/messageeditor.h index 21b3405..0fbf658 100644 --- a/tools/linguist/linguist/messageeditor.h +++ b/tools/linguist/linguist/messageeditor.h @@ -114,7 +114,7 @@ public slots: private slots: void editorCreated(QTextEdit *); - void editorDeleted(QTextEdit *); + void editorDestroyed(); void selectionChanged(QTextEdit *); void resetHoverSelection(); void emitTranslationChanged(QTextEdit *); diff --git a/tools/linguist/linguist/messageeditorwidgets.cpp b/tools/linguist/linguist/messageeditorwidgets.cpp index 29df673..042ef3d 100644 --- a/tools/linguist/linguist/messageeditorwidgets.cpp +++ b/tools/linguist/linguist/messageeditorwidgets.cpp @@ -130,6 +130,11 @@ FormatTextEdit::FormatTextEdit(QWidget *parent) m_highlighter = new MessageHighlighter(this); } +FormatTextEdit::~FormatTextEdit() +{ + emit editorDestroyed(); +} + void FormatTextEdit::setEditable(bool editable) { // save default frame style @@ -362,11 +367,9 @@ void FormMultiWidget::setTranslation(const QString &text, bool userAction) QStringList texts = text.split(QChar(Translator::BinaryVariantSeparator), QString::KeepEmptyParts); while (m_editors.count() > texts.count()) { - FormatTextEdit *editor = m_editors.takeLast(); - emit editorDeleted(editor); delete m_minusButtons.takeLast(); delete m_plusButtons.takeLast(); - delete editor; + delete m_editors.takeLast(); } while (m_editors.count() < texts.count()) addEditor(m_editors.count()); diff --git a/tools/linguist/linguist/messageeditorwidgets.h b/tools/linguist/linguist/messageeditorwidgets.h index 1f6f1f5..c6d9201 100644 --- a/tools/linguist/linguist/messageeditorwidgets.h +++ b/tools/linguist/linguist/messageeditorwidgets.h @@ -91,8 +91,12 @@ class FormatTextEdit : public ExpandingTextEdit Q_OBJECT public: FormatTextEdit(QWidget *parent = 0); + ~FormatTextEdit(); void setEditable(bool editable); +signals: + void editorDestroyed(); + public slots: void setPlainText(const QString & text, bool userAction); @@ -150,7 +154,6 @@ public: signals: void editorCreated(QTextEdit *); - void editorDeleted(QTextEdit *); void textChanged(QTextEdit *); void selectionChanged(QTextEdit *); void cursorPositionChanged(); diff --git a/tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp b/tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp index bc617a9..9c49183 100644 --- a/tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp +++ b/tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp @@ -466,11 +466,13 @@ static QString stringify(const QString &data) int i; for (i = 0; i < data.length(); ++i) { retval += QLatin1Char('\"'); - for ( ; i < data.length() && data[i] != QLatin1Char('\n'); ++i) + for ( ; i < data.length() && data[i] != QLatin1Char('\n') && data[i] != QLatin1Char('\r'); ++i) if (data[i] == QLatin1Char('\"')) retval += QLatin1String("\\\""); else retval += data[i]; + if (data[i] == QLatin1Char('\r') && data[i+1] == QLatin1Char('\n')) + i++; retval += QLatin1String("\\n\"\n"); } return retval; |