diff options
author | Friedemann Kleint <Friedemann.Kleint@theqtcompany.com> | 2014-11-07 10:58:04 +0100 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@theqtcompany.com> | 2014-11-07 12:24:54 +0100 |
commit | 46c51861822c4ee8f0e7d7f5ecc23d1595cf5c1d (patch) | |
tree | 463a71dd1c9a98be5a901f2d32d8cecac678112c | |
parent | fc3606b94daa8b40e32f7d5ae01c54e0a0e1a235 (diff) | |
download | qtactiveqt-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.cpp | 63 | ||||
-rw-r--r-- | src/activeqt/container/qaxbase.h | 13 | ||||
-rw-r--r-- | src/activeqt/container/qaxscript.cpp | 9 | ||||
-rw-r--r-- | tests/auto/auto.pro | 4 | ||||
-rw-r--r-- | tests/auto/qaxscript/qaxscript.pro | 3 | ||||
-rw-r--r-- | tests/auto/qaxscript/tst_qaxscript.cpp | 63 |
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" |