From 413003fe4f9e8c3ee2a0d892e627d8e268a8e866 Mon Sep 17 00:00:00 2001 From: wraitii Date: Sat, 31 Oct 2020 10:13:33 +0000 Subject: [PATCH] Fix a compartment mismatch in XmppClient, causing crashes in MP games. Added in 9023f4bebb, which changed lobby GUI messages to JS::Values, requiring a real context. The original code mistakenly inverted the owning script interfaces. Given the reproducibility discovered in SM52, the timeline of the bug, and the nature of the issues encountered in MP, this is a rather safe fix for #5655. Reviewed By: Itms Fixes #5655 Differential Revision: https://code.wildfiregames.com/D2922 This was SVN commit r24116. --- source/lobby/XmppClient.cpp | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/source/lobby/XmppClient.cpp b/source/lobby/XmppClient.cpp index ec2a07e638..98d0094ea4 100644 --- a/source/lobby/XmppClient.cpp +++ b/source/lobby/XmppClient.cpp @@ -703,7 +703,7 @@ JS::Value XmppClient::GuiPollNewMessages(const ScriptInterface& scriptInterface) if ((m_isConnected && !m_initialLoadComplete) || m_GuiMessageQueue.empty()) return JS::UndefinedValue(); - JSContext* cx = scriptInterface.GetContext(); + JSContext* cx = m_ScriptInterface->GetContext(); JSAutoRequest rq(cx); // Optimize for batch message processing that is more @@ -715,34 +715,35 @@ JS::Value XmppClient::GuiPollNewMessages(const ScriptInterface& scriptInterface) for (const JS::Heap& message : m_GuiMessageQueue) { - scriptInterface.SetPropertyInt(messages, j++, message); + m_ScriptInterface->SetPropertyInt(messages, j++, message); // Store historic chat messages. // Only store relevant messages to minimize memory footprint. JS::RootedValue rootedMessage(cx, message); std::string type; - scriptInterface.GetProperty(rootedMessage, "type", type); + m_ScriptInterface->GetProperty(rootedMessage, "type", type); if (type != "chat") continue; std::string level; - scriptInterface.GetProperty(rootedMessage, "level", level); + m_ScriptInterface->GetProperty(rootedMessage, "level", level); if (level != "room-message" && level != "private-message") continue; JS::RootedValue historicMessage(cx); if (JS_StructuredClone(cx, rootedMessage, &historicMessage, nullptr, nullptr)) { - scriptInterface.SetProperty(historicMessage, "historic", true); - scriptInterface.FreezeObject(historicMessage, true); + m_ScriptInterface->SetProperty(historicMessage, "historic", true); + m_ScriptInterface->FreezeObject(historicMessage, true); m_HistoricGuiMessages.push_back(JS::Heap(historicMessage)); } else LOGERROR("Could not clone historic lobby GUI message!"); } - m_GuiMessageQueue.clear(); - return messages; + + // Copy the messages over to the caller script interface. + return scriptInterface.CloneValueFromOtherContext(*m_ScriptInterface, messages); } JS::Value XmppClient::GuiPollHistoricMessages(const ScriptInterface& scriptInterface) @@ -750,7 +751,7 @@ JS::Value XmppClient::GuiPollHistoricMessages(const ScriptInterface& scriptInter if (m_HistoricGuiMessages.empty()) return JS::UndefinedValue(); - JSContext* cx = scriptInterface.GetContext(); + JSContext* cx = m_ScriptInterface->GetContext(); JSAutoRequest rq(cx); JS::RootedValue messages(cx); @@ -758,9 +759,10 @@ JS::Value XmppClient::GuiPollHistoricMessages(const ScriptInterface& scriptInter int j = 0; for (const JS::Heap& message : m_HistoricGuiMessages) - scriptInterface.SetPropertyInt(messages, j++, message); + m_ScriptInterface->SetPropertyInt(messages, j++, message); - return messages; + // Copy the messages over to the caller script interface. + return scriptInterface.CloneValueFromOtherContext(*m_ScriptInterface, messages); } /**