aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKahrl <kahrl@gmx.net>2015-09-29 01:55:12 +0200
committerKahrl <kahrl@gmx.net>2015-09-29 01:55:12 +0200
commit0cde03254a6564eaec21603e9add4f14e6c2fe52 (patch)
treeffe8ccdecd450f8a8c419936415b3e35b8b2c529
parentffe291cb78fc7135034fe6456b2d7dfc3761dc52 (diff)
downloadminetest-0cde03254a6564eaec21603e9add4f14e6c2fe52.tar.gz
minetest-0cde03254a6564eaec21603e9add4f14e6c2fe52.tar.bz2
minetest-0cde03254a6564eaec21603e9add4f14e6c2fe52.zip
Don't serialize StaticObjectList with > 65535 objects
Because the count is serialized as u16, this would cause overflow. If minetest later deserialized a mapblock with an incorrect static object count, it would be unable to find the NameIdMapping (which comes after the StaticObjectList) and abort with an error such as "Invalid block data in database: unsupported NameIdMapping version" (issue #2610).
-rw-r--r--src/staticobject.cpp14
1 files changed, 13 insertions, 1 deletions
diff --git a/src/staticobject.cpp b/src/staticobject.cpp
index 2e7d45a47..e226f0b2e 100644
--- a/src/staticobject.cpp
+++ b/src/staticobject.cpp
@@ -19,6 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "staticobject.h"
#include "util/serialize.h"
+#include "log.h"
void StaticObject::serialize(std::ostream &os)
{
@@ -44,9 +45,20 @@ void StaticObjectList::serialize(std::ostream &os)
// version
u8 version = 0;
writeU8(os, version);
+
// count
- u16 count = m_stored.size() + m_active.size();
+ size_t count = m_stored.size() + m_active.size();
+ // Make sure it fits into u16, else it would get truncated and cause e.g.
+ // issue #2610 (Invalid block data in database: unsupported NameIdMapping version).
+ if (count > (u16)-1) {
+ errorstream << "StaticObjectList::serialize(): "
+ << "too many objects (" << count << ") in list, "
+ << "not writing them to disk." << std::endl;
+ writeU16(os, 0); // count = 0
+ return;
+ }
writeU16(os, count);
+
for(std::vector<StaticObject>::iterator
i = m_stored.begin();
i != m_stored.end(); ++i) {