mirror of
https://github.com/minetest/minetest.git
synced 2024-11-27 10:03:45 +01:00
Limit formspec fields to 640K (#13380)
Fixes an issue where long inputs could cause issues when dealing with formspecs. The expected data is usually below 1 KiB, however that's not a technical limit.
This commit is contained in:
parent
7048fc25dd
commit
d975ebdcb9
@ -1342,21 +1342,26 @@ void Server::handleCommand_RemovedSounds(NetworkPacket* pkt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::handleCommand_NodeMetaFields(NetworkPacket* pkt)
|
static bool pkt_read_formspec_fields(NetworkPacket *pkt, StringMap &fields)
|
||||||
{
|
{
|
||||||
v3s16 p;
|
u16 field_count;
|
||||||
std::string formname;
|
*pkt >> field_count;
|
||||||
u16 num;
|
|
||||||
|
|
||||||
*pkt >> p >> formname >> num;
|
u64 length = 0;
|
||||||
|
for (u16 k = 0; k < field_count; k++) {
|
||||||
StringMap fields;
|
|
||||||
for (u16 k = 0; k < num; k++) {
|
|
||||||
std::string fieldname;
|
std::string fieldname;
|
||||||
*pkt >> fieldname;
|
*pkt >> fieldname;
|
||||||
fields[fieldname] = pkt->readLongString();
|
fields[fieldname] = pkt->readLongString();
|
||||||
}
|
|
||||||
|
|
||||||
|
length += fieldname.size();
|
||||||
|
length += fields[fieldname].size();
|
||||||
|
}
|
||||||
|
// 640K ought to be enough for anyone
|
||||||
|
return length < 640 * 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Server::handleCommand_NodeMetaFields(NetworkPacket* pkt)
|
||||||
|
{
|
||||||
session_t peer_id = pkt->getPeerId();
|
session_t peer_id = pkt->getPeerId();
|
||||||
RemotePlayer *player = m_env->getPlayer(peer_id);
|
RemotePlayer *player = m_env->getPlayer(peer_id);
|
||||||
|
|
||||||
@ -1377,6 +1382,18 @@ void Server::handleCommand_NodeMetaFields(NetworkPacket* pkt)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
v3s16 p;
|
||||||
|
std::string formname;
|
||||||
|
StringMap fields;
|
||||||
|
|
||||||
|
*pkt >> p >> formname;
|
||||||
|
|
||||||
|
if (!pkt_read_formspec_fields(pkt, fields)) {
|
||||||
|
warningstream << "Too large formspec fields! Ignoring for pos="
|
||||||
|
<< PP(p) << ", player=" << player->getName() << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// If something goes wrong, this player is to blame
|
// If something goes wrong, this player is to blame
|
||||||
RollbackScopeActor rollback_scope(m_rollback,
|
RollbackScopeActor rollback_scope(m_rollback,
|
||||||
std::string("player:")+player->getName());
|
std::string("player:")+player->getName());
|
||||||
@ -1397,18 +1414,6 @@ void Server::handleCommand_NodeMetaFields(NetworkPacket* pkt)
|
|||||||
|
|
||||||
void Server::handleCommand_InventoryFields(NetworkPacket* pkt)
|
void Server::handleCommand_InventoryFields(NetworkPacket* pkt)
|
||||||
{
|
{
|
||||||
std::string client_formspec_name;
|
|
||||||
u16 num;
|
|
||||||
|
|
||||||
*pkt >> client_formspec_name >> num;
|
|
||||||
|
|
||||||
StringMap fields;
|
|
||||||
for (u16 k = 0; k < num; k++) {
|
|
||||||
std::string fieldname;
|
|
||||||
*pkt >> fieldname;
|
|
||||||
fields[fieldname] = pkt->readLongString();
|
|
||||||
}
|
|
||||||
|
|
||||||
session_t peer_id = pkt->getPeerId();
|
session_t peer_id = pkt->getPeerId();
|
||||||
RemotePlayer *player = m_env->getPlayer(peer_id);
|
RemotePlayer *player = m_env->getPlayer(peer_id);
|
||||||
|
|
||||||
@ -1429,6 +1434,17 @@ void Server::handleCommand_InventoryFields(NetworkPacket* pkt)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string client_formspec_name;
|
||||||
|
StringMap fields;
|
||||||
|
|
||||||
|
*pkt >> client_formspec_name;
|
||||||
|
|
||||||
|
if (!pkt_read_formspec_fields(pkt, fields)) {
|
||||||
|
warningstream << "Too large formspec fields! Ignoring for formname=\""
|
||||||
|
<< client_formspec_name << "\", player=" << player->getName() << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (client_formspec_name.empty()) { // pass through inventory submits
|
if (client_formspec_name.empty()) { // pass through inventory submits
|
||||||
m_script->on_playerReceiveFields(playersao, client_formspec_name, fields);
|
m_script->on_playerReceiveFields(playersao, client_formspec_name, fields);
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user