summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/dbus/qdbusdemarshaller.cpp24
-rw-r--r--tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp82
-rw-r--r--tools/linguist/linguist/messageeditor.cpp12
-rw-r--r--tools/linguist/linguist/messageeditor.h2
-rw-r--r--tools/linguist/linguist/messageeditorwidgets.cpp9
-rw-r--r--tools/linguist/linguist/messageeditorwidgets.h5
-rw-r--r--tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp4
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;