forked from qt-creator/qt-creator
JavaScriptFilter: Use QScriptEngine to avoid endless loops
QJSEngine does not provide a means to interrupt the evaluation when then engine stucks in an endless loop. The (deprecated) QScriptEngine does allow this, so use this for now. As QBS also needs QScriptEngine, no extra dependency is created. For Qt installations without QtScript, the JavaScriptFilter is not compiled. Task-number: QTCREATORBUG-19690 Change-Id: I172b7e7042eea0d40a765c836b2d1c57b6a529e6 Reviewed-by: hjk <hjk@qt.io> Reviewed-by: Eike Ziller <eike.ziller@qt.io> Reviewed-by: Orgad Shaneh <orgads@gmail.com>
This commit is contained in:
committed by
André Hartmann
parent
38807f3ded
commit
5f69507573
@@ -17,11 +17,18 @@ Project {
|
|||||||
condition: qbs.targetOS.contains("windows")
|
condition: qbs.targetOS.contains("windows")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Depends { name: "Qt.script"; required: false }
|
||||||
|
|
||||||
Depends { name: "Utils" }
|
Depends { name: "Utils" }
|
||||||
Depends { name: "Aggregation" }
|
Depends { name: "Aggregation" }
|
||||||
|
|
||||||
Depends { name: "app_version_header" }
|
Depends { name: "app_version_header" }
|
||||||
|
|
||||||
|
Properties {
|
||||||
|
condition: Qt.script.present
|
||||||
|
cpp.defines: base.concat("WITH_JAVASCRIPTFILTER")
|
||||||
|
}
|
||||||
|
|
||||||
cpp.dynamicLibraries: {
|
cpp.dynamicLibraries: {
|
||||||
if (qbs.targetOS.contains("windows"))
|
if (qbs.targetOS.contains("windows"))
|
||||||
return ["ole32", "user32"]
|
return ["ole32", "user32"]
|
||||||
@@ -343,8 +350,6 @@ Project {
|
|||||||
"filesystemfilter.ui",
|
"filesystemfilter.ui",
|
||||||
"ilocatorfilter.cpp",
|
"ilocatorfilter.cpp",
|
||||||
"ilocatorfilter.h",
|
"ilocatorfilter.h",
|
||||||
"javascriptfilter.cpp",
|
|
||||||
"javascriptfilter.h",
|
|
||||||
"locatorconstants.h",
|
"locatorconstants.h",
|
||||||
"locatorfiltersfilter.cpp",
|
"locatorfiltersfilter.cpp",
|
||||||
"locatorfiltersfilter.h",
|
"locatorfiltersfilter.h",
|
||||||
@@ -364,6 +369,16 @@ Project {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Group {
|
||||||
|
name: "Locator Javascript Filter"
|
||||||
|
condition: Qt.script.present
|
||||||
|
prefix: "locator/"
|
||||||
|
files: [
|
||||||
|
"javascriptfilter.cpp",
|
||||||
|
"javascriptfilter.h",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
Group {
|
Group {
|
||||||
name: "Locator_mac"
|
name: "Locator_mac"
|
||||||
condition: qbs.targetOS.contains("macos")
|
condition: qbs.targetOS.contains("macos")
|
||||||
|
@@ -27,14 +27,16 @@
|
|||||||
|
|
||||||
#include <QClipboard>
|
#include <QClipboard>
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
#include <QJSEngine>
|
#include <QScriptEngine>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
enum JavaScriptAction
|
enum JavaScriptAction
|
||||||
{
|
{
|
||||||
ResetEngine = QVariant::UserType + 1
|
ResetEngine = QVariant::UserType + 1,
|
||||||
|
AbortEngine
|
||||||
};
|
};
|
||||||
|
|
||||||
JavaScriptFilter::JavaScriptFilter()
|
JavaScriptFilter::JavaScriptFilter()
|
||||||
@@ -66,13 +68,25 @@ QList<LocatorFilterEntry> JavaScriptFilter::matchesFor(
|
|||||||
if (entry.trimmed().isEmpty()) {
|
if (entry.trimmed().isEmpty()) {
|
||||||
entries.append({this, tr("Reset Engine"), QVariant(ResetEngine, nullptr)});
|
entries.append({this, tr("Reset Engine"), QVariant(ResetEngine, nullptr)});
|
||||||
} else {
|
} else {
|
||||||
const QString result = m_engine->evaluate(entry).toString();
|
bool aborted = false;
|
||||||
const QString expression = entry + " = " + result;
|
|
||||||
|
|
||||||
|
QTimer::singleShot(1000, this, [this, &aborted]() {
|
||||||
|
m_engine->abortEvaluation();
|
||||||
|
aborted = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
const QString result = m_engine->evaluate(entry).toString();
|
||||||
|
|
||||||
|
if (aborted) {
|
||||||
|
const QString message = entry + " = " + tr("Engine aborted after timeout.");
|
||||||
|
entries.append({this, message, QVariant(AbortEngine, nullptr)});
|
||||||
|
} else {
|
||||||
|
const QString expression = entry + " = " + result;
|
||||||
entries.append({this, expression, QVariant()});
|
entries.append({this, expression, QVariant()});
|
||||||
entries.append({this, tr("Copy to clipboard: %1").arg(result), result});
|
entries.append({this, tr("Copy to clipboard: %1").arg(result), result});
|
||||||
entries.append({this, tr("Copy to clipboard: %1").arg(expression), expression});
|
entries.append({this, tr("Copy to clipboard: %1").arg(expression), expression});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return entries;
|
return entries;
|
||||||
}
|
}
|
||||||
@@ -104,7 +118,7 @@ void JavaScriptFilter::refresh(QFutureInterface<void> &future)
|
|||||||
|
|
||||||
void JavaScriptFilter::setupEngine()
|
void JavaScriptFilter::setupEngine()
|
||||||
{
|
{
|
||||||
m_engine.reset(new QJSEngine);
|
m_engine.reset(new QScriptEngine);
|
||||||
m_engine->evaluate(
|
m_engine->evaluate(
|
||||||
"function abs(x) { return Math.abs(x); }\n"
|
"function abs(x) { return Math.abs(x); }\n"
|
||||||
"function acos(x) { return Math.acos(x); }\n"
|
"function acos(x) { return Math.acos(x); }\n"
|
||||||
|
@@ -30,7 +30,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
class QJSEngine;
|
class QScriptEngine;
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
@@ -53,7 +53,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
void setupEngine();
|
void setupEngine();
|
||||||
|
|
||||||
mutable std::unique_ptr<QJSEngine> m_engine;
|
mutable std::unique_ptr<QScriptEngine> m_engine;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -122,8 +122,10 @@ void Locator::initialize(CorePlugin *corePlugin, const QStringList &, QString *)
|
|||||||
|
|
||||||
new LocatorManager(this);
|
new LocatorManager(this);
|
||||||
|
|
||||||
|
#ifdef WITH_JAVASCRIPTFILTER
|
||||||
m_javaScriptFilter = new JavaScriptFilter;
|
m_javaScriptFilter = new JavaScriptFilter;
|
||||||
m_corePlugin->addObject(m_javaScriptFilter);
|
m_corePlugin->addObject(m_javaScriptFilter);
|
||||||
|
#endif
|
||||||
|
|
||||||
m_openDocumentsFilter = new OpenDocumentsFilter;
|
m_openDocumentsFilter = new OpenDocumentsFilter;
|
||||||
m_corePlugin->addObject(m_openDocumentsFilter);
|
m_corePlugin->addObject(m_openDocumentsFilter);
|
||||||
|
@@ -15,8 +15,7 @@ HEADERS += \
|
|||||||
$$PWD/executefilter.h \
|
$$PWD/executefilter.h \
|
||||||
$$PWD/locatorsearchutils.h \
|
$$PWD/locatorsearchutils.h \
|
||||||
$$PWD/locatorsettingspage.h \
|
$$PWD/locatorsettingspage.h \
|
||||||
$$PWD/externaltoolsfilter.h \
|
$$PWD/externaltoolsfilter.h
|
||||||
$$PWD/javascriptfilter.h
|
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
$$PWD/locator.cpp \
|
$$PWD/locator.cpp \
|
||||||
@@ -33,7 +32,18 @@ SOURCES += \
|
|||||||
$$PWD/locatorsearchutils.cpp \
|
$$PWD/locatorsearchutils.cpp \
|
||||||
$$PWD/locatorsettingspage.cpp \
|
$$PWD/locatorsettingspage.cpp \
|
||||||
$$PWD/externaltoolsfilter.cpp \
|
$$PWD/externaltoolsfilter.cpp \
|
||||||
|
|
||||||
|
qtHaveModule(script) {
|
||||||
|
QT *= script
|
||||||
|
|
||||||
|
DEFINES += WITH_JAVASCRIPTFILTER
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
$$PWD/javascriptfilter.h
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
$$PWD/javascriptfilter.cpp
|
$$PWD/javascriptfilter.cpp
|
||||||
|
}
|
||||||
|
|
||||||
FORMS += \
|
FORMS += \
|
||||||
$$PWD/filesystemfilter.ui \
|
$$PWD/filesystemfilter.ui \
|
||||||
|
Reference in New Issue
Block a user