From e41f010f9137568234ae946dc4b2f4461f3d49a8 Mon Sep 17 00:00:00 2001 From: Yves Date: Mon, 4 Aug 2014 20:14:17 +0000 Subject: [PATCH] Fixes crash when loading maps in Atlas. The ScriptInterface pointer can be NULL there, so using it without checking is not safe. This fixes the problem by continuing with the exact stack rooting changes, which makes the temporary solution unnecessary. Fixes #2707 Refs #2415 This was SVN commit r15611. --- source/gui/GUIManager.cpp | 7 +------ source/gui/GUIManager.h | 2 +- source/gui/scripting/ScriptFunctions.cpp | 7 ++++++- source/ps/GameSetup/GameSetup.cpp | 12 ++++++------ .../atlas/GameInterface/Handlers/MiscHandlers.cpp | 2 +- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/source/gui/GUIManager.cpp b/source/gui/GUIManager.cpp index 5392b58383..5c7ae614ab 100644 --- a/source/gui/GUIManager.cpp +++ b/source/gui/GUIManager.cpp @@ -71,13 +71,8 @@ bool CGUIManager::HasPages() return !m_PageStack.empty(); } -void CGUIManager::SwitchPage(const CStrW& pageName, ScriptInterface* srcScriptInterface, CScriptVal initData1) +void CGUIManager::SwitchPage(const CStrW& pageName, ScriptInterface* srcScriptInterface, JS::HandleValue initData) { - JSContext* cx = srcScriptInterface->GetContext(); - JSAutoRequest rq(cx); - // TODO: Get Handle parameter directly with SpiderMonkey 31 - JS::RootedValue initData(cx, initData1.get()); - // The page stack is cleared (including the script context where initData came from), // therefore we have to clone initData. shared_ptr initDataClone; diff --git a/source/gui/GUIManager.h b/source/gui/GUIManager.h index 40dca70242..428adac510 100644 --- a/source/gui/GUIManager.h +++ b/source/gui/GUIManager.h @@ -66,7 +66,7 @@ public: /** * Load a new GUI page and make it active. All current pages will be destroyed. */ - void SwitchPage(const CStrW& name, ScriptInterface* srcScriptInterface, CScriptVal initData); + void SwitchPage(const CStrW& name, ScriptInterface* srcScriptInterface, JS::HandleValue initData); /** * Load a new GUI page and make it active. All current pages will be retained, diff --git a/source/gui/scripting/ScriptFunctions.cpp b/source/gui/scripting/ScriptFunctions.cpp index c1a0dd1522..43d442cd18 100644 --- a/source/gui/scripting/ScriptFunctions.cpp +++ b/source/gui/scripting/ScriptFunctions.cpp @@ -96,8 +96,13 @@ void PushGuiPage(ScriptInterface::CxPrivate* pCxPrivate, std::wstring name, CScr g_GUI->PushPage(name, pCxPrivate->pScriptInterface->WriteStructuredClone(initData)); } -void SwitchGuiPage(ScriptInterface::CxPrivate* pCxPrivate, std::wstring name, CScriptVal initData) +void SwitchGuiPage(ScriptInterface::CxPrivate* pCxPrivate, std::wstring name, CScriptVal initData1) { + JSContext* cx = pCxPrivate->pScriptInterface->GetContext(); + JSAutoRequest rq(cx); + // TODO: Get Handle parameter directly with SpiderMonkey 31 + JS::RootedValue initData(cx, initData1.get()); + g_GUI->SwitchPage(name, pCxPrivate->pScriptInterface, initData); } diff --git a/source/ps/GameSetup/GameSetup.cpp b/source/ps/GameSetup/GameSetup.cpp index dcfbc1113d..2139fed956 100644 --- a/source/ps/GameSetup/GameSetup.cpp +++ b/source/ps/GameSetup/GameSetup.cpp @@ -485,7 +485,7 @@ static void InitVfs(const CmdLineArgs& args, int flags) } -static void InitPs(bool setup_gui, const CStrW& gui_page, ScriptInterface* srcScriptInterface, CScriptVal initData) +static void InitPs(bool setup_gui, const CStrW& gui_page, ScriptInterface* srcScriptInterface, JS::HandleValue initData) { { // console @@ -1029,7 +1029,7 @@ void InitGraphics(const CmdLineArgs& args, int flags) scriptInterface->Eval("({})", &data); scriptInterface->SetProperty(data, "isStartup", true); } - InitPs(setup_gui, L"page_pregame.xml", g_GUI->GetScriptInterface().get(), data.get()); + InitPs(setup_gui, L"page_pregame.xml", g_GUI->GetScriptInterface().get(), data); } } catch (PSERROR_Game_World_MapLoadFailed& e) @@ -1037,7 +1037,7 @@ void InitGraphics(const CmdLineArgs& args, int flags) // Map Loading failed // Start the engine so we have a GUI - InitPs(true, L"page_pregame.xml", NULL, JSVAL_VOID); + InitPs(true, L"page_pregame.xml", NULL, JS::UndefinedHandleValue); // Call script function to do the actual work // (delete game data, switch GUI page, show error, etc.) @@ -1352,7 +1352,7 @@ bool Autostart(const CmdLineArgs& args) if (args.Has("autostart-host")) { - InitPs(true, L"page_loading.xml", &scriptInterface, mpInitData.get()); + InitPs(true, L"page_loading.xml", &scriptInterface, mpInitData); size_t maxPlayers = 2; if (args.Has("autostart-players")) @@ -1373,7 +1373,7 @@ bool Autostart(const CmdLineArgs& args) } else if (args.Has("autostart-client")) { - InitPs(true, L"page_loading.xml", &scriptInterface, mpInitData.get()); + InitPs(true, L"page_loading.xml", &scriptInterface, mpInitData); g_NetClient = new CNetClient(g_Game); g_NetClient->SetUserName(userName); @@ -1397,7 +1397,7 @@ bool Autostart(const CmdLineArgs& args) PSRETURN ret = g_Game->ReallyStartGame(); ENSURE(ret == PSRETURN_OK); - InitPs(true, L"page_session.xml", NULL, JSVAL_VOID); + InitPs(true, L"page_session.xml", NULL, JS::UndefinedHandleValue); } return true; diff --git a/source/tools/atlas/GameInterface/Handlers/MiscHandlers.cpp b/source/tools/atlas/GameInterface/Handlers/MiscHandlers.cpp index c69681caa2..8251b1f9fa 100644 --- a/source/tools/atlas/GameInterface/Handlers/MiscHandlers.cpp +++ b/source/tools/atlas/GameInterface/Handlers/MiscHandlers.cpp @@ -154,7 +154,7 @@ MESSAGEHANDLER(JavaScript) MESSAGEHANDLER(GuiSwitchPage) { - g_GUI->SwitchPage(*msg->page, NULL, JSVAL_VOID); + g_GUI->SwitchPage(*msg->page, NULL, JS::UndefinedHandleValue); } MESSAGEHANDLER(GuiMouseButtonEvent)