diff --git a/src/object_properties.cpp b/src/object_properties.cpp index 2eebc27d6..db06f8930 100644 --- a/src/object_properties.cpp +++ b/src/object_properties.cpp @@ -83,6 +83,39 @@ std::string ObjectProperties::dump() return os.str(); } +bool ObjectProperties::validate() +{ + const char *func = "ObjectProperties::validate(): "; + bool ret = true; + + // cf. where serializeString16 is used below + for (u32 i = 0; i < textures.size(); i++) { + if (textures[i].size() > U16_MAX) { + warningstream << func << "texture " << (i+1) << " has excessive length, " + "clearing it." << std::endl; + textures[i].clear(); + ret = false; + } + } + if (nametag.length() > U16_MAX) { + warningstream << func << "nametag has excessive length, clearing it." << std::endl; + nametag.clear(); + ret = false; + } + if (infotext.length() > U16_MAX) { + warningstream << func << "infotext has excessive length, clearing it." << std::endl; + infotext.clear(); + ret = false; + } + if (wield_item.length() > U16_MAX) { + warningstream << func << "wield_item has excessive length, clearing it." << std::endl; + wield_item.clear(); + ret = false; + } + + return ret; +} + void ObjectProperties::serialize(std::ostream &os) const { writeU8(os, 4); // PROTOCOL_VERSION >= 37 @@ -105,7 +138,6 @@ void ObjectProperties::serialize(std::ostream &os) const writeU8(os, is_visible); writeU8(os, makes_footstep_sound); writeF32(os, automatic_rotate); - // Added in protocol version 14 os << serializeString16(mesh); writeU16(os, colors.size()); for (video::SColor color : colors) { diff --git a/src/object_properties.h b/src/object_properties.h index db28eebfd..79866a22c 100644 --- a/src/object_properties.h +++ b/src/object_properties.h @@ -68,6 +68,8 @@ struct ObjectProperties ObjectProperties(); std::string dump(); + // check limits of some important properties (strings) that'd cause exceptions later on + bool validate(); void serialize(std::ostream &os) const; void deSerialize(std::istream &is); }; diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index 8e308cd9e..c404cb63c 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -685,6 +685,7 @@ int ObjectRef::l_set_properties(lua_State *L) return 0; read_object_properties(L, 2, sao, prop, getServer(L)->idef()); + prop->validate(); sao->notifyObjectPropertiesModified(); return 0; } @@ -752,6 +753,7 @@ int ObjectRef::l_set_nametag_attributes(lua_State *L) std::string nametag = getstringfield_default(L, 2, "text", ""); prop->nametag = nametag; + prop->validate(); sao->notifyObjectPropertiesModified(); lua_pushboolean(L, true); return 1; diff --git a/src/staticobject.cpp b/src/staticobject.cpp index 86e455b9f..1160ec68f 100644 --- a/src/staticobject.cpp +++ b/src/staticobject.cpp @@ -37,6 +37,7 @@ void StaticObject::serialize(std::ostream &os) // data os< bool { + if (obj.data.size() > U16_MAX) { + errorstream << "StaticObjectList::serialize(): " + "object has excessive static data (" << obj.data.size() << + "), deleting it." << std::endl; + return true; + } + return false; + }; + for (auto it = m_stored.begin(); it != m_stored.end(); ) { + if (problematic(*it)) + it = m_stored.erase(it); + else + it++; + } + for (auto it = m_active.begin(); it != m_active.end(); ) { + if (problematic(it->second)) + it = m_active.erase(it); + else + it++; + } + // version u8 version = 0; writeU8(os, version);