summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@theqtcompany.com>2014-11-07 10:58:04 +0100
committerFriedemann Kleint <Friedemann.Kleint@theqtcompany.com>2014-11-07 12:24:54 +0100
commit46c51861822c4ee8f0e7d7f5ecc23d1595cf5c1d (patch)
tree463a71dd1c9a98be5a901f2d32d8cecac678112c
parentfc3606b94daa8b40e32f7d5ae01c54e0a0e1a235 (diff)
downloadqtactiveqt-46c51861822c4ee8f0e7d7f5ecc23d1595cf5c1d.tar.gz
Suppress DISPATCH_PROPERTYGET for calls from QAxScript.
Factor out a version QAxBase::dynamicCall() taking a flag that allows for suppressing DISPATCH_PROPERTYGET and use that from QAxScript to fix return types. Add autotest. Task-number: QTBUG-42289 Change-Id: I1900061bc2de6d5987cb7323bb388df806e53e96 Reviewed-by: Andy Shaw <andy.shaw@digia.com>
-rw-r--r--src/activeqt/container/qaxbase.cpp63
-rw-r--r--src/activeqt/container/qaxbase.h13
-rw-r--r--src/activeqt/container/qaxscript.cpp9
-rw-r--r--tests/auto/auto.pro4
-rw-r--r--tests/auto/qaxscript/qaxscript.pro3
-rw-r--r--tests/auto/qaxscript/tst_qaxscript.cpp63
6 files changed, 128 insertions, 27 deletions
diff --git a/src/activeqt/container/qaxbase.cpp b/src/activeqt/container/qaxbase.cpp
index c038992..803f3a4 100644
--- a/src/activeqt/container/qaxbase.cpp
+++ b/src/activeqt/container/qaxbase.cpp
@@ -3814,7 +3814,8 @@ static void qax_noSuchFunction(int disptype, const QByteArray &name, const QByte
\a name is already normalized?
*/
-bool QAxBase::dynamicCallHelper(const char *name, void *inout, QList<QVariant> &vars, QByteArray &type)
+bool QAxBase::dynamicCallHelper(const char *name, void *inout, QList<QVariant> &vars,
+ QByteArray &type, unsigned flags)
{
if (isNull()) {
qWarning("QAxBase::dynamicCallHelper: Object is not initialized, or initialization failed");
@@ -3845,7 +3846,9 @@ bool QAxBase::dynamicCallHelper(const char *name, void *inout, QList<QVariant> &
bool parse = false;
if (function.contains('(')) {
- disptype = DISPATCH_METHOD | DISPATCH_PROPERTYGET;
+ disptype = DISPATCH_METHOD;
+ if (!(flags & NoPropertyGet))
+ disptype |= DISPATCH_PROPERTYGET; // Support Excel/VB.
if (d->useMetaObject)
id = mo->indexOfSlot(function);
if (id >= 0) {
@@ -4026,6 +4029,32 @@ bool QAxBase::dynamicCallHelper(const char *name, void *inout, QList<QVariant> &
return checkHRESULT(hres, &excepinfo, this, QLatin1String(function), varc-argerr-1);
}
+/*!
+ \internal
+*/
+QVariantList QAxBase::argumentsToList(const QVariant &var1, const QVariant &var2,
+ const QVariant &var3, const QVariant &var4,
+ const QVariant &var5, const QVariant &var6,
+ const QVariant &var7, const QVariant &var8)
+{
+ QVariantList vars;
+ QVariant var = var1;
+ int argc = 1;
+ while (var.isValid()) {
+ vars << var;
+ switch (++argc) {
+ case 2: var = var2; break;
+ case 3: var = var3; break;
+ case 4: var = var4; break;
+ case 5: var = var5; break;
+ case 6: var = var6; break;
+ case 7: var = var7; break;
+ case 8: var = var8; break;
+ default:var = QVariant(); break;
+ }
+ }
+ return vars;
+}
/*!
Calls the COM object's method \a function, passing the
@@ -4086,24 +4115,8 @@ QVariant QAxBase::dynamicCall(const char *function,
const QVariant &var7,
const QVariant &var8)
{
- QList<QVariant> vars;
- QVariant var = var1;
- int argc = 1;
- while(var.isValid()) {
- vars << var;
- switch(++argc) {
- case 2: var = var2; break;
- case 3: var = var3; break;
- case 4: var = var4; break;
- case 5: var = var5; break;
- case 6: var = var6; break;
- case 7: var = var7; break;
- case 8: var = var8; break;
- default:var = QVariant(); break;
- }
- }
-
- return dynamicCall(function, vars);
+ QVariantList vars = QAxBase::argumentsToList(var1, var2, var3, var4, var5, var6, var7, var8);
+ return dynamicCall(function, vars); // Use overload taking "QVariantList &" to avoid recursion
}
/*!
@@ -4120,11 +4133,19 @@ QVariant QAxBase::dynamicCall(const char *function,
*/
QVariant QAxBase::dynamicCall(const char *function, QList<QVariant> &vars)
{
+ return dynamicCall(function, vars, 0);
+}
+
+/*!
+ \internal
+*/
+QVariant QAxBase::dynamicCall(const char *function, QList<QVariant> &vars, unsigned flags)
+{
VARIANTARG res;
VariantInit(&res);
QByteArray rettype;
- if (!dynamicCallHelper(function, &res, vars, rettype))
+ if (!dynamicCallHelper(function, &res, vars, rettype, flags))
return QVariant();
QVariant qvar = VARIANTToQVariant(res, rettype);
diff --git a/src/activeqt/container/qaxbase.h b/src/activeqt/container/qaxbase.h
index e406183..31c6a41 100644
--- a/src/activeqt/container/qaxbase.h
+++ b/src/activeqt/container/qaxbase.h
@@ -137,6 +137,11 @@ protected:
void initializeFrom(QAxBase *that);
void connectNotify();
long indexOfVerb(const QString &verb) const;
+ QVariant dynamicCall(const char *name, QList<QVariant> &vars, unsigned flags);
+ static QVariantList argumentsToList(const QVariant &var1, const QVariant &var2,
+ const QVariant &var3, const QVariant &var4,
+ const QVariant &var5, const QVariant &var6,
+ const QVariant &var7, const QVariant &var8);
virtual const QMetaObject *fallbackMetaObject() const = 0;
@@ -148,6 +153,11 @@ protected:
static const uint qt_meta_data_QAxBase[];
private:
+ enum DynamicCallHelperFlags {
+ NoPropertyGet = 0x1 // Suppresses DISPATCH_PROPERTYGET, use for plain functions.
+ };
+
+ friend class QAxScript;
friend class QAxEventSink;
friend void *qax_createObjectWrapper(int, IUnknown*);
bool initializeLicensedHelper(void *factory, const QString &key, IUnknown **ptr);
@@ -157,7 +167,8 @@ private:
virtual const QMetaObject *parentMetaObject() const = 0;
int internalProperty(QMetaObject::Call, int index, void **v);
int internalInvoke(QMetaObject::Call, int index, void **v);
- bool dynamicCallHelper(const char *name, void *out, QList<QVariant> &var, QByteArray &type);
+ bool dynamicCallHelper(const char *name, void *out, QList<QVariant> &var,
+ QByteArray &type, unsigned flags = 0);
};
template <> inline QAxBase *qobject_cast<QAxBase*>(const QObject *o)
diff --git a/src/activeqt/container/qaxscript.cpp b/src/activeqt/container/qaxscript.cpp
index fe426d2..046260e 100644
--- a/src/activeqt/container/qaxscript.cpp
+++ b/src/activeqt/container/qaxscript.cpp
@@ -778,10 +778,8 @@ QVariant QAxScript::call(const QString &function, const QVariant &var1,
const QVariant &var7,
const QVariant &var8)
{
- if (!script_engine)
- return QVariant();
-
- return script_engine->dynamicCall(function.toLatin1(), var1, var2, var3, var4, var5, var6, var7, var8);
+ QVariantList vars = QAxBase::argumentsToList(var1, var2, var3, var4, var5, var6, var7, var8);
+ return call(function, vars);
}
/*!
@@ -798,7 +796,8 @@ QVariant QAxScript::call(const QString &function, QList<QVariant> &arguments)
if (!script_engine)
return QVariant();
- return script_engine->dynamicCall(function.toLatin1(), arguments);
+ return script_engine->dynamicCall(function.toLatin1(), arguments,
+ QAxBase::NoPropertyGet);
}
/*! \internal
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro
index 41abb07..593ed3f 100644
--- a/tests/auto/auto.pro
+++ b/tests/auto/auto.pro
@@ -1,5 +1,9 @@
TEMPLATE = subdirs
SUBDIRS += \
qaxobject \
+ qaxscript \
dumpcpp \
cmake
+
+*g++*: SUBDIRS -= \
+ qaxscript \
diff --git a/tests/auto/qaxscript/qaxscript.pro b/tests/auto/qaxscript/qaxscript.pro
new file mode 100644
index 0000000..704b2cd
--- /dev/null
+++ b/tests/auto/qaxscript/qaxscript.pro
@@ -0,0 +1,3 @@
+CONFIG += testcase
+QT = core axcontainer testlib
+SOURCES += tst_qaxscript.cpp
diff --git a/tests/auto/qaxscript/tst_qaxscript.cpp b/tests/auto/qaxscript/tst_qaxscript.cpp
new file mode 100644
index 0000000..45a16b0
--- /dev/null
+++ b/tests/auto/qaxscript/tst_qaxscript.cpp
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+#include <QAxScriptManager>
+#include <QAxScript>
+
+class tst_QAxScript : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void scriptReturnValue();
+};
+
+void tst_QAxScript::scriptReturnValue()
+{
+ QAxScriptManager scriptManager;
+ const char scriptCode[] =
+ "function foo() {\n"
+ " return 'test';\n"
+ "}\n"; // QTBUG-42289, fails when DISPATCH_PROPERTYGET is used.
+ QAxScript *script = scriptManager.load(QLatin1String(scriptCode),
+ QStringLiteral("Test"),
+ QStringLiteral("JScript"));
+ QVERIFY2(script, "Unable to load script (CoInitialize() called?)");
+ const QVariant result = script->call("foo()");
+ QCOMPARE(result, QVariant(QStringLiteral("test")));
+}
+
+QTEST_MAIN(tst_QAxScript)
+#include "tst_qaxscript.moc"