From c1afa356c0e9ce3c753e449b0a030f006faabda0 Mon Sep 17 00:00:00 2001 From: Harri Porten Date: Tue, 11 Feb 2020 22:34:46 +0000 Subject: [PATCH] Restrict time given for JavaScript evaluation to max. 2 seconds. Possible improvement: alert the user of the timeout and offer the option to continue or abort execution. --- CMakeLists.txt | 10 ++++++++++ config-okular.h.cmake | 2 ++ core/script/executor_kjs.cpp | 12 +++++++++++- core/script/kjs_app.cpp | 14 +++++++++++++- 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2166dc0b1..f76f11659 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -339,6 +339,16 @@ if (KF5JS_FOUND) core/script/kjs_ocg.cpp ) target_link_libraries(okularcore PRIVATE KF5::JS KF5::JSApi) + set(CMAKE_REQUIRED_LIBRARIES KF5::JSApi) + check_cxx_source_compiles(" +#include +int main() +{ + KJSInterpreter *ip = 0; + ip->setTimeoutTime(0); + return 0; +} +" HAVE_KJS_TIMEOUT) endif() set_target_properties(okularcore PROPERTIES VERSION 9.0.0 SOVERSION 9 OUTPUT_NAME Okular5Core EXPORT_NAME Core) diff --git a/config-okular.h.cmake b/config-okular.h.cmake index b999a1c39..c55f6530d 100644 --- a/config-okular.h.cmake +++ b/config-okular.h.cmake @@ -7,3 +7,5 @@ /* Defines whether the malloc_trim method from malloc.h is available */ #cmakedefine01 HAVE_MALLOC_TRIM +/* Defines if we have timeout support in the KJS library */ +#cmakedefine HAVE_KJS_TIMEOUT 1 diff --git a/core/script/executor_kjs.cpp b/core/script/executor_kjs.cpp index aff02c862..3d32268ca 100644 --- a/core/script/executor_kjs.cpp +++ b/core/script/executor_kjs.cpp @@ -21,6 +21,7 @@ #include "../document_p.h" #include "event_p.h" +#include "config-okular.h" #include "kjs_app_p.h" #include "kjs_console_p.h" #include "kjs_data_p.h" @@ -60,6 +61,9 @@ void ExecutorKJSPrivate::initTypes() m_docObject = JSDocument::wrapDocument( m_doc ); m_interpreter = new KJSInterpreter( m_docObject ); +#ifdef HAVE_KJS_TIMEOUT + m_interpreter->setTimeoutTime( 2000 ); // max 2 secs allowed +#endif KJSContext *ctx = m_interpreter->globalContext(); JSApp::initType( ctx ); @@ -113,9 +117,15 @@ void ExecutorKJS::execute( const QString &script, Event *event ) d->m_docObject.setProperty( ctx, QStringLiteral("event"), event ? JSEvent::wrapEvent( ctx, event ) : KJSUndefined() ); +#ifdef HAVE_KJS_TIMEOUT + d->m_interpreter->startTimeoutCheck(); +#endif KJSResult result = d->m_interpreter->evaluate( QStringLiteral("okular.js"), 1, script, &d->m_docObject ); - +#ifdef HAVE_KJS_TIMEOUT + d->m_interpreter->stopTimeoutCheck(); +#endif + if ( result.isException() || ctx->hasException() ) { qCDebug(OkularCoreDebug) << "JS exception" << result.errorMessage(); diff --git a/core/script/kjs_app.cpp b/core/script/kjs_app.cpp index 3404356da..57d66bf84 100644 --- a/core/script/kjs_app.cpp +++ b/core/script/kjs_app.cpp @@ -11,6 +11,7 @@ #include "kjs_app_p.h" #include +#include #include #include @@ -25,6 +26,7 @@ #include "../document_p.h" #include "../scripter.h" +#include "config-okular.h" #include "kjs_fullscreen_p.h" using namespace Okular; @@ -236,9 +238,19 @@ static KJSObject appAlert( KJSContext *context, void *, box.setCheckBox( checkBox ); } - + +#ifdef HAVE_KJS_TIMEOUT + // halt timeout until the user has responded + context->interpreter().stopTimeoutCheck(); +#endif + int button = box.exec(); +#ifdef HAVE_KJS_TIMEOUT + // restart max allowed time + context->interpreter().startTimeoutCheck(); +#endif + int ret; switch( button )