From 2661110292d34299f157c8f7913f11e17087d826 Mon Sep 17 00:00:00 2001 From: past-due <30942300+past-due@users.noreply.github.com> Date: Wed, 13 Sep 2023 15:58:44 -0400 Subject: [PATCH 1/4] Update quickjs-wz --- 3rdparty/quickjs-wz | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rdparty/quickjs-wz b/3rdparty/quickjs-wz index a30ecb3bf25..163ce747d27 160000 --- a/3rdparty/quickjs-wz +++ b/3rdparty/quickjs-wz @@ -1 +1 @@ -Subproject commit a30ecb3bf25d820f6e3f7e7f698d84b21a00199d +Subproject commit 163ce747d271dfc3cfdc0dac92e342390c445ffd From 9aaca7985c38d4bd8f985bb24f5ad3dfd020f479 Mon Sep 17 00:00:00 2001 From: past-due <30942300+past-due@users.noreply.github.com> Date: Wed, 13 Sep 2023 15:59:36 -0400 Subject: [PATCH 2/4] wzmaplib: More restrictive script map environment --- lib/wzmaplib/src/map_script.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/wzmaplib/src/map_script.cpp b/lib/wzmaplib/src/map_script.cpp index b36429975ba..4eee1acddce 100644 --- a/lib/wzmaplib/src/map_script.cpp +++ b/lib/wzmaplib/src/map_script.cpp @@ -715,7 +715,7 @@ std::shared_ptr runMapScript(const std::vector& fileBuffer, const std JSLimitedContextOptions ctxOptions; ctxOptions.baseObjects = true; ctxOptions.dateObject = false; - ctxOptions.eval = true; // required for JS_Eval to work + ctxOptions.eval = false; ctxOptions.stringNormalize = false; ctxOptions.regExp = false; ctxOptions.json = false; @@ -745,7 +745,7 @@ std::shared_ptr runMapScript(const std::vector& fileBuffer, const std return nullptr; } size_t fileBufLen = fileBuffer.size() - 1; - JSValue compiledScriptObj = JS_Eval(ctx, fileBuffer.data(), fileBufLen, path.c_str(), JS_EVAL_TYPE_GLOBAL | JS_EVAL_FLAG_COMPILE_ONLY); + JSValue compiledScriptObj = JS_Eval_BypassLimitedContext(ctx, fileBuffer.data(), fileBufLen, path.c_str(), JS_EVAL_TYPE_GLOBAL | JS_EVAL_FLAG_COMPILE_ONLY); if (JS_IsException(compiledScriptObj)) { // compilation error / syntax error From 381b59297755cd48d1261469665fb9f75fea5627 Mon Sep 17 00:00:00 2001 From: past-due <30942300+past-due@users.noreply.github.com> Date: Wed, 13 Sep 2023 16:00:27 -0400 Subject: [PATCH 3/4] wzmaplib: Bump version to 1.2.3 --- lib/wzmaplib/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/wzmaplib/CMakeLists.txt b/lib/wzmaplib/CMakeLists.txt index 1047bd9e698..58781180a8e 100644 --- a/lib/wzmaplib/CMakeLists.txt +++ b/lib/wzmaplib/CMakeLists.txt @@ -3,7 +3,7 @@ set(WZMAPLIB_VERSION_MAJOR 1) set(WZMAPLIB_VERSION_MINOR 2) -set(WZMAPLIB_VERSION_REV 2) +set(WZMAPLIB_VERSION_REV 3) ################### # Determine minimum CMake version From 6c9b7e7c38e4c69d487938f24ec0923ebd344dff Mon Sep 17 00:00:00 2001 From: past-due <30942300+past-due@users.noreply.github.com> Date: Wed, 13 Sep 2023 19:51:30 -0400 Subject: [PATCH 4/4] quickjs_backend: Customize JS context - Disable `eval` for everything except campaign (which currently has lots of implicit eval usage) - Disable promises, await, etc (which don't work) --- src/quickjs_backend.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/quickjs_backend.cpp b/src/quickjs_backend.cpp index b9e209df269..cab3b4a76c4 100644 --- a/src/quickjs_backend.cpp +++ b/src/quickjs_backend.cpp @@ -151,8 +151,21 @@ class quickjs_scripting_instance : public wzapi::scripting_instance { rt = JS_NewRuntime(); ASSERT(rt != nullptr, "JS_NewRuntime failed?"); - ctx = JS_NewContext(rt); + + JSLimitedContextOptions ctxOptions; + ctxOptions.baseObjects = true; + ctxOptions.dateObject = true; + ctxOptions.eval = (game.type == LEVEL_TYPE::CAMPAIGN); // allow "eval" only for campaign (which currently has lots of implicit eval usage) + ctxOptions.stringNormalize = true; + ctxOptions.regExp = true; + ctxOptions.json = true; + ctxOptions.proxy = true; + ctxOptions.mapSet = true; + ctxOptions.typedArrays = true; + ctxOptions.promise = false; // disable promise, async, await + ctx = JS_NewLimitedContext(rt, &ctxOptions); ASSERT(ctx != nullptr, "JS_NewContext failed?"); + global_obj = JS_GetGlobalObject(ctx); engineToInstanceMap.insert(std::pair(ctx, this)); @@ -2321,7 +2334,7 @@ static JSValue js_include(JSContext *ctx, JSValueConst this_val, int argc, JSVal JS_ThrowReferenceError(ctx, "Failed to read include file \"%s\"", filePath.c_str()); return JS_FALSE; } - JSValue compiledFuncObj = JS_Eval(ctx, bytes, size, loadedFilePath.c_str(), JS_EVAL_TYPE_GLOBAL | JS_EVAL_FLAG_COMPILE_ONLY); + JSValue compiledFuncObj = JS_Eval_BypassLimitedContext(ctx, bytes, size, loadedFilePath.c_str(), JS_EVAL_TYPE_GLOBAL | JS_EVAL_FLAG_COMPILE_ONLY); free(bytes); if (JS_IsException(compiledFuncObj)) { @@ -2668,7 +2681,7 @@ bool quickjs_scripting_instance::loadScript(const WzString& path, int player, in calcDataHash(reinterpret_cast(bytes), size, DATA_SCRIPT); } m_path = path.toUtf8(); - compiledScriptObj = JS_Eval(ctx, bytes, size, path.toUtf8().c_str(), JS_EVAL_TYPE_GLOBAL | JS_EVAL_FLAG_COMPILE_ONLY); + compiledScriptObj = JS_Eval_BypassLimitedContext(ctx, bytes, size, path.toUtf8().c_str(), JS_EVAL_TYPE_GLOBAL | JS_EVAL_FLAG_COMPILE_ONLY); free(bytes); if (JS_IsException(compiledScriptObj)) { @@ -2833,7 +2846,7 @@ std::unordered_map", JS_EVAL_TYPE_GLOBAL | JS_EVAL_FLAG_COMPILE_ONLY); + JSValue compiledFuncObj = JS_Eval_BypassLimitedContext(ctx, text.c_str(), text.length(), "", JS_EVAL_TYPE_GLOBAL | JS_EVAL_FLAG_COMPILE_ONLY); if (JS_IsException(compiledFuncObj)) { // compilation error / syntax error