mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
Client: protect against circular attachments (#16038)
The server already includes such check. There must be a desync issue that causes an ID mismatch, resulting in client crashes. Any such crash must be prevented.
This commit is contained in:
parent
c0e42c6588
commit
5c6e4d35b0
2 changed files with 30 additions and 2 deletions
|
@ -411,6 +411,32 @@ void GenericCAO::setChildrenVisible(bool toset)
|
||||||
void GenericCAO::setAttachment(object_t parent_id, const std::string &bone,
|
void GenericCAO::setAttachment(object_t parent_id, const std::string &bone,
|
||||||
v3f position, v3f rotation, bool force_visible)
|
v3f position, v3f rotation, bool force_visible)
|
||||||
{
|
{
|
||||||
|
// Do checks to avoid circular references
|
||||||
|
// See similar check in `UnitSAO::setAttachment` (but with different types).
|
||||||
|
{
|
||||||
|
auto *obj = m_env->getActiveObject(parent_id);
|
||||||
|
if (obj == this) {
|
||||||
|
assert(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bool problem = false;
|
||||||
|
if (obj) {
|
||||||
|
// The chain of wanted parent must not refer or contain "this"
|
||||||
|
for (obj = obj->getParent(); obj; obj = obj->getParent()) {
|
||||||
|
if (obj == this) {
|
||||||
|
problem = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (problem) {
|
||||||
|
warningstream << "Network or mod bug: "
|
||||||
|
<< "Attempted to attach object " << m_id << " to parent "
|
||||||
|
<< parent_id << " but former is an (in)direct parent of latter." << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const auto old_parent = m_attachment_parent_id;
|
const auto old_parent = m_attachment_parent_id;
|
||||||
m_attachment_parent_id = parent_id;
|
m_attachment_parent_id = parent_id;
|
||||||
m_attachment_bone = bone;
|
m_attachment_bone = bone;
|
||||||
|
|
|
@ -128,8 +128,9 @@ void UnitSAO::setAttachment(const object_t new_parent, const std::string &bone,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Do checks to avoid circular references
|
// Do checks to avoid circular references
|
||||||
|
// See similar check in `GenericCAO::setAttachment` (but with different types).
|
||||||
{
|
{
|
||||||
auto *obj = new_parent ? m_env->getActiveObject(new_parent) : nullptr;
|
auto *obj = m_env->getActiveObject(new_parent);
|
||||||
if (obj == this) {
|
if (obj == this) {
|
||||||
assert(false);
|
assert(false);
|
||||||
return;
|
return;
|
||||||
|
@ -145,7 +146,8 @@ void UnitSAO::setAttachment(const object_t new_parent, const std::string &bone,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (problem) {
|
if (problem) {
|
||||||
warningstream << "Mod bug: Attempted to attach object " << m_id << " to parent "
|
warningstream << "Mod bug: "
|
||||||
|
<< "Attempted to attach object " << m_id << " to parent "
|
||||||
<< new_parent << " but former is an (in)direct parent of latter." << std::endl;
|
<< new_parent << " but former is an (in)direct parent of latter." << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue