Protect against server or CSM messing with the settings formspec
This commit is contained in:
parent
5304767bdc
commit
aae26818c1
@ -671,7 +671,8 @@ local function buttonhandler(this, fields)
|
|||||||
dialogdata.rightscroll = core.explode_scrollbar_event(fields.rightscroll).value or dialogdata.rightscroll
|
dialogdata.rightscroll = core.explode_scrollbar_event(fields.rightscroll).value or dialogdata.rightscroll
|
||||||
dialogdata.query = fields.search_query
|
dialogdata.query = fields.search_query
|
||||||
|
|
||||||
if fields.back then
|
-- "quit" is for the pause menu env
|
||||||
|
if fields.back or fields.quit then
|
||||||
this:delete()
|
this:delete()
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
@ -782,14 +783,21 @@ else
|
|||||||
|
|
||||||
core.register_on_formspec_input(function(formname, fields)
|
core.register_on_formspec_input(function(formname, fields)
|
||||||
if dialog and formname == "__builtin:settings" then
|
if dialog and formname == "__builtin:settings" then
|
||||||
-- dialog is re-checked since the buttonhandler may have closed it
|
-- buttonhandler returning true means we should update the formspec.
|
||||||
|
-- dialog is re-checked since the buttonhandler may have closed it.
|
||||||
if buttonhandler(dialog, fields) and dialog then
|
if buttonhandler(dialog, fields) and dialog then
|
||||||
core.show_formspec("__builtin:settings", get_formspec(dialog.data))
|
core.show_formspec("__builtin:settings", get_formspec(dialog.data))
|
||||||
end
|
end
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
core.open_settings = function()
|
core.open_settings = function()
|
||||||
|
-- this assert is here to make sure we catch all cases of closing the dialog.
|
||||||
|
-- this is also a little additional protection against processing input
|
||||||
|
-- we shouldn't process (e.g. coming from server-sent formspecs).
|
||||||
|
assert(not dialog)
|
||||||
|
|
||||||
load()
|
load()
|
||||||
dialog = {}
|
dialog = {}
|
||||||
dialog.data = {}
|
dialog.data = {}
|
||||||
|
@ -22,7 +22,8 @@ enum ClientEventType : u8
|
|||||||
CE_PLAYER_FORCE_MOVE,
|
CE_PLAYER_FORCE_MOVE,
|
||||||
CE_DEATHSCREEN_LEGACY,
|
CE_DEATHSCREEN_LEGACY,
|
||||||
CE_SHOW_FORMSPEC,
|
CE_SHOW_FORMSPEC,
|
||||||
CE_SHOW_LOCAL_FORMSPEC,
|
CE_SHOW_CSM_FORMSPEC,
|
||||||
|
CE_SHOW_PAUSE_MENU_FORMSPEC,
|
||||||
CE_SPAWN_PARTICLE,
|
CE_SPAWN_PARTICLE,
|
||||||
CE_ADD_PARTICLESPAWNER,
|
CE_ADD_PARTICLESPAWNER,
|
||||||
CE_DELETE_PARTICLESPAWNER,
|
CE_DELETE_PARTICLESPAWNER,
|
||||||
|
@ -646,7 +646,8 @@ private:
|
|||||||
void handleClientEvent_PlayerForceMove(ClientEvent *event, CameraOrientation *cam);
|
void handleClientEvent_PlayerForceMove(ClientEvent *event, CameraOrientation *cam);
|
||||||
void handleClientEvent_DeathscreenLegacy(ClientEvent *event, CameraOrientation *cam);
|
void handleClientEvent_DeathscreenLegacy(ClientEvent *event, CameraOrientation *cam);
|
||||||
void handleClientEvent_ShowFormSpec(ClientEvent *event, CameraOrientation *cam);
|
void handleClientEvent_ShowFormSpec(ClientEvent *event, CameraOrientation *cam);
|
||||||
void handleClientEvent_ShowLocalFormSpec(ClientEvent *event, CameraOrientation *cam);
|
void handleClientEvent_ShowCSMFormSpec(ClientEvent *event, CameraOrientation *cam);
|
||||||
|
void handleClientEvent_ShowPauseMenuFormSpec(ClientEvent *event, CameraOrientation *cam);
|
||||||
void handleClientEvent_HandleParticleEvent(ClientEvent *event,
|
void handleClientEvent_HandleParticleEvent(ClientEvent *event,
|
||||||
CameraOrientation *cam);
|
CameraOrientation *cam);
|
||||||
void handleClientEvent_HudAdd(ClientEvent *event, CameraOrientation *cam);
|
void handleClientEvent_HudAdd(ClientEvent *event, CameraOrientation *cam);
|
||||||
@ -2552,7 +2553,8 @@ const ClientEventHandler Game::clientEventHandler[CLIENTEVENT_MAX] = {
|
|||||||
{&Game::handleClientEvent_PlayerForceMove},
|
{&Game::handleClientEvent_PlayerForceMove},
|
||||||
{&Game::handleClientEvent_DeathscreenLegacy},
|
{&Game::handleClientEvent_DeathscreenLegacy},
|
||||||
{&Game::handleClientEvent_ShowFormSpec},
|
{&Game::handleClientEvent_ShowFormSpec},
|
||||||
{&Game::handleClientEvent_ShowLocalFormSpec},
|
{&Game::handleClientEvent_ShowCSMFormSpec},
|
||||||
|
{&Game::handleClientEvent_ShowPauseMenuFormSpec},
|
||||||
{&Game::handleClientEvent_HandleParticleEvent},
|
{&Game::handleClientEvent_HandleParticleEvent},
|
||||||
{&Game::handleClientEvent_HandleParticleEvent},
|
{&Game::handleClientEvent_HandleParticleEvent},
|
||||||
{&Game::handleClientEvent_HandleParticleEvent},
|
{&Game::handleClientEvent_HandleParticleEvent},
|
||||||
@ -2620,9 +2622,18 @@ void Game::handleClientEvent_ShowFormSpec(ClientEvent *event, CameraOrientation
|
|||||||
delete event->show_formspec.formname;
|
delete event->show_formspec.formname;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::handleClientEvent_ShowLocalFormSpec(ClientEvent *event, CameraOrientation *cam)
|
void Game::handleClientEvent_ShowCSMFormSpec(ClientEvent *event, CameraOrientation *cam)
|
||||||
{
|
{
|
||||||
m_game_formspec.showLocalFormSpec(*event->show_formspec.formspec,
|
m_game_formspec.showCSMFormSpec(*event->show_formspec.formspec,
|
||||||
|
*event->show_formspec.formname);
|
||||||
|
|
||||||
|
delete event->show_formspec.formspec;
|
||||||
|
delete event->show_formspec.formname;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Game::handleClientEvent_ShowPauseMenuFormSpec(ClientEvent *event, CameraOrientation *cam)
|
||||||
|
{
|
||||||
|
m_game_formspec.showPauseMenuFormSpec(*event->show_formspec.formspec,
|
||||||
*event->show_formspec.formname);
|
*event->show_formspec.formname);
|
||||||
|
|
||||||
delete event->show_formspec.formspec;
|
delete event->show_formspec.formspec;
|
||||||
|
@ -228,16 +228,29 @@ void GameFormSpec::showFormSpec(const std::string &formspec, const std::string &
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameFormSpec::showLocalFormSpec(const std::string &formspec, const std::string &formname)
|
void GameFormSpec::showCSMFormSpec(const std::string &formspec, const std::string &formname)
|
||||||
{
|
{
|
||||||
FormspecFormSource *fs_src = new FormspecFormSource(formspec);
|
FormspecFormSource *fs_src = new FormspecFormSource(formspec);
|
||||||
LocalFormspecHandler *txt_dst =
|
LocalFormspecHandler *txt_dst =
|
||||||
new LocalFormspecHandler(formname, m_client, m_pause_script.get());
|
new LocalFormspecHandler(formname, m_client, nullptr);
|
||||||
GUIFormSpecMenu::create(m_formspec, m_client, m_rendering_engine->get_gui_env(),
|
GUIFormSpecMenu::create(m_formspec, m_client, m_rendering_engine->get_gui_env(),
|
||||||
&m_input->joystick, fs_src, txt_dst, m_client->getFormspecPrepend(),
|
&m_input->joystick, fs_src, txt_dst, m_client->getFormspecPrepend(),
|
||||||
m_client->getSoundManager());
|
m_client->getSoundManager());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GameFormSpec::showPauseMenuFormSpec(const std::string &formspec, const std::string &formname)
|
||||||
|
{
|
||||||
|
// Neither CSM nor the server must be allowed to mess with the settings formspec,
|
||||||
|
// it's a trusted context like the mainmenu.
|
||||||
|
FormspecFormSource *fs_src = new FormspecFormSource(formspec);
|
||||||
|
LocalFormspecHandler *txt_dst =
|
||||||
|
new LocalFormspecHandler(formname, nullptr, m_pause_script.get());
|
||||||
|
GUIFormSpecMenu::create(m_formspec, m_client, m_rendering_engine->get_gui_env(),
|
||||||
|
// Ignore formspec prepend.
|
||||||
|
&m_input->joystick, fs_src, txt_dst, "",
|
||||||
|
m_client->getSoundManager());
|
||||||
|
}
|
||||||
|
|
||||||
void GameFormSpec::showNodeFormspec(const std::string &formspec, const v3s16 &nodepos)
|
void GameFormSpec::showNodeFormspec(const std::string &formspec, const v3s16 &nodepos)
|
||||||
{
|
{
|
||||||
infostream << "Launching custom inventory view" << std::endl;
|
infostream << "Launching custom inventory view" << std::endl;
|
||||||
@ -417,7 +430,7 @@ void GameFormSpec::showDeathFormspecLegacy()
|
|||||||
/* Note: FormspecFormSource and LocalFormspecHandler *
|
/* Note: FormspecFormSource and LocalFormspecHandler *
|
||||||
* are deleted by guiFormSpecMenu */
|
* are deleted by guiFormSpecMenu */
|
||||||
FormspecFormSource *fs_src = new FormspecFormSource(formspec_str);
|
FormspecFormSource *fs_src = new FormspecFormSource(formspec_str);
|
||||||
LocalFormspecHandler *txt_dst = new LocalFormspecHandler("MT_DEATH_SCREEN", m_client, m_pause_script.get());
|
LocalFormspecHandler *txt_dst = new LocalFormspecHandler("MT_DEATH_SCREEN", m_client, nullptr);
|
||||||
|
|
||||||
GUIFormSpecMenu::create(m_formspec, m_client, m_rendering_engine->get_gui_env(),
|
GUIFormSpecMenu::create(m_formspec, m_client, m_rendering_engine->get_gui_env(),
|
||||||
&m_input->joystick, fs_src, txt_dst, m_client->getFormspecPrepend(),
|
&m_input->joystick, fs_src, txt_dst, m_client->getFormspecPrepend(),
|
||||||
|
@ -36,7 +36,8 @@ struct GameFormSpec
|
|||||||
~GameFormSpec();
|
~GameFormSpec();
|
||||||
|
|
||||||
void showFormSpec(const std::string &formspec, const std::string &formname);
|
void showFormSpec(const std::string &formspec, const std::string &formname);
|
||||||
void showLocalFormSpec(const std::string &formspec, const std::string &formname);
|
void showCSMFormSpec(const std::string &formspec, const std::string &formname);
|
||||||
|
void showPauseMenuFormSpec(const std::string &formspec, const std::string &formname);
|
||||||
void showNodeFormspec(const std::string &formspec, const v3s16 &nodepos);
|
void showNodeFormspec(const std::string &formspec, const v3s16 &nodepos);
|
||||||
void showPlayerInventory();
|
void showPlayerInventory();
|
||||||
void showDeathFormspecLegacy();
|
void showDeathFormspecLegacy();
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include "client/client.h"
|
#include "client/client.h"
|
||||||
#include "client/clientevent.h"
|
#include "client/clientevent.h"
|
||||||
|
#include "cpp_api/s_base.h"
|
||||||
#include "lua_api/l_internal.h"
|
#include "lua_api/l_internal.h"
|
||||||
|
|
||||||
// show_formspec(formspec)
|
// show_formspec(formspec)
|
||||||
@ -15,7 +16,9 @@ int ModApiClientCommon::l_show_formspec(lua_State *L)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ClientEvent *event = new ClientEvent();
|
ClientEvent *event = new ClientEvent();
|
||||||
event->type = CE_SHOW_LOCAL_FORMSPEC;
|
event->type = getScriptApiBase(L)->getType() == ScriptingType::PauseMenu
|
||||||
|
? CE_SHOW_PAUSE_MENU_FORMSPEC
|
||||||
|
: CE_SHOW_CSM_FORMSPEC;
|
||||||
event->show_formspec.formname = new std::string(luaL_checkstring(L, 1));
|
event->show_formspec.formname = new std::string(luaL_checkstring(L, 1));
|
||||||
event->show_formspec.formspec = new std::string(luaL_checkstring(L, 2));
|
event->show_formspec.formspec = new std::string(luaL_checkstring(L, 2));
|
||||||
getClient(L)->pushToEventQueue(event);
|
getClient(L)->pushToEventQueue(event);
|
||||||
|
Loading…
Reference in New Issue
Block a user