From df871d3c8e89821acf5c0863dc9be2b216f22939 Mon Sep 17 00:00:00 2001 From: mihacooper Date: Mon, 23 Jan 2017 15:07:20 +0300 Subject: [PATCH] Fix segfault by initialization of BaseHolder type --- src/shared-table.cpp | 3 +- src/stored-object.cpp | 31 +++++------------ src/stored-object.h | 8 +---- tests/shared-table.cpp | 76 +++++++++++++++++++++--------------------- 4 files changed, 49 insertions(+), 69 deletions(-) diff --git a/src/shared-table.cpp b/src/shared-table.cpp index a73efe6..90d0dc9 100644 --- a/src/shared-table.cpp +++ b/src/shared-table.cpp @@ -22,7 +22,8 @@ void SharedTable::set(StoredObject key, StoredObject value) noexcept { } void SharedTable::luaSet(sol::stack_object luaKey, sol::stack_object luaValue) noexcept { - assert(luaKey.valid()); + if (!luaKey.valid()) + throw sol::error("Invalid table index"); StoredObject key(luaKey); if (luaValue.get_type() == sol::type::nil) { diff --git a/src/stored-object.cpp b/src/stored-object.cpp index 2e33bac..4cf2702 100644 --- a/src/stored-object.cpp +++ b/src/stored-object.cpp @@ -17,24 +17,19 @@ template class PrimitiveHolder : public BaseHolder { public: PrimitiveHolder(sol::stack_object luaObject) noexcept - : data_(luaObject.as()) {} + : BaseHolder(luaObject.get_type()), data_(luaObject.as()) {} PrimitiveHolder(sol::object luaObject) noexcept - : data_(luaObject.as()) {} + : BaseHolder(luaObject.get_type()), data_(luaObject.as()) {} - PrimitiveHolder(const StoredType& init) noexcept - : data_(init) {} + PrimitiveHolder(sol::type type, const StoredType& init) noexcept + : BaseHolder(type), data_(init) {} bool rawCompare(const BaseHolder* other) const noexcept final { assert(type_ == other->type()); return static_cast*>(other)->data_ == data_; } - bool rawLess(const BaseHolder* other) const noexcept final { - assert(type_ == other->type()); - return data_ < static_cast*>(other)->data_; - } - std::size_t hash() const noexcept final { return std::hash()(data_); } @@ -50,7 +45,8 @@ private: class FunctionHolder : public BaseHolder { public: template - FunctionHolder(SolObject luaObject) noexcept { + FunctionHolder(SolObject luaObject) noexcept + : BaseHolder(sol::type::function) { sol::state_view lua(luaObject.lua_state()); sol::function dumper = lua["string"]["dump"]; @@ -62,10 +58,6 @@ public: return function_ == static_cast(other)->function_; } - bool rawLess(const BaseHolder* other) const noexcept final { - return function_ < static_cast(other)->function_; - } - std::size_t hash() const noexcept final { return std::hash()(function_); } @@ -149,7 +141,7 @@ std::unique_ptr fromSolObject(SolObject luaObject) { // SolTableToShared is used to prevent from infinity recursion // in recursive tables dumpTable(table, luaTable, visited); - return std::make_unique>(table); + return std::make_unique>(sol::type::userdata, table); } default: ERROR << "Unable to store object of that type: " << (int)luaObject.get_type() << std::endl; @@ -163,7 +155,7 @@ StoredObject::StoredObject(StoredObject&& init) noexcept : data_(std::move(init.data_)) {} StoredObject::StoredObject(SharedTable* table) noexcept - : data_(new PrimitiveHolder(table)) { + : data_(new PrimitiveHolder(sol::type::userdata, table)) { } StoredObject::StoredObject(sol::object object) noexcept @@ -204,11 +196,4 @@ bool StoredObject::operator==(const StoredObject& o) const noexcept { return data_.get() == o.data_.get(); } -bool StoredObject::operator<(const StoredObject& o) const noexcept { - if (data_) - return data_->less(o.data_.get()); - else - return data_.get() < o.data_.get(); -} - } // effil diff --git a/src/stored-object.h b/src/stored-object.h index 9a70bc2..87f1d53 100644 --- a/src/stored-object.h +++ b/src/stored-object.h @@ -9,7 +9,7 @@ namespace effil { class BaseHolder { public: - BaseHolder() noexcept : type_(sol::type::nil) {} + BaseHolder(sol::type t) noexcept : type_(t) {} virtual ~BaseHolder() = default; sol::type type() const noexcept { @@ -20,13 +20,8 @@ public: assert(other != nullptr); return type_ == other->type_ && rawCompare(other); } - virtual bool less(const BaseHolder* other) const noexcept { - assert(other != nullptr); - return type_ < other->type_ && rawLess(other); - } virtual bool rawCompare(const BaseHolder* other) const noexcept = 0; - virtual bool rawLess(const BaseHolder* other) const noexcept = 0; virtual std::size_t hash() const noexcept = 0; virtual sol::object unpack(sol::this_state state) const noexcept = 0; @@ -53,7 +48,6 @@ public: sol::object unpack(sol::this_state state) const noexcept; StoredObject& operator=(StoredObject&& o) noexcept; bool operator==(const StoredObject& o) const noexcept; - bool operator<(const StoredObject& o) const noexcept; private: std::unique_ptr data_; diff --git a/tests/shared-table.cpp b/tests/shared-table.cpp index 5607863..2054ab5 100644 --- a/tests/shared-table.cpp +++ b/tests/shared-table.cpp @@ -34,12 +34,12 @@ st.del = "secret" st.del = nil )"); - ASSERT_TRUE(res1.valid()) << "Set res1 failed"; - ASSERT_EQ(lua["st"]["fst"], std::string("first")); - ASSERT_EQ(lua["st"]["snd"], (double)2); - ASSERT_EQ(lua["st"]["thr"], true); - ASSERT_EQ(lua["st"]["del"], sol::nil); - ASSERT_EQ(lua["st"]["nex"], sol::nil); + EXPECT_TRUE(res1.valid()) << "Set res1 failed"; + EXPECT_EQ(lua["st"]["fst"], std::string("first")); + EXPECT_EQ(lua["st"]["snd"], (double)2); + EXPECT_EQ(lua["st"]["thr"], true); + EXPECT_EQ(lua["st"]["del"], sol::nil); + EXPECT_EQ(lua["st"]["nex"], sol::nil); auto res2 = lua.script(R"( st[1] = 3 @@ -50,20 +50,20 @@ st[42] = nil st.deleted = st[42] == nil )"); - ASSERT_TRUE(res2.valid()) << "Set res2 failed"; - ASSERT_EQ(lua["st"][1], 3); - ASSERT_EQ(lua["st"][2], std::string("number")); - ASSERT_EQ(lua["st"][-1], false); - ASSERT_EQ(lua["st"]["deleted"], true); + EXPECT_TRUE(res2.valid()) << "Set res2 failed"; + EXPECT_EQ(lua["st"][1], 3); + EXPECT_EQ(lua["st"][2], std::string("number")); + EXPECT_EQ(lua["st"][-1], false); + EXPECT_EQ(lua["st"]["deleted"], true); auto res3 = lua.script(R"( st[true] = false st[false] = 9 )"); - ASSERT_TRUE(res3.valid()) << "Set res3 failed"; - ASSERT_EQ(lua["st"][true], false); - ASSERT_EQ(lua["st"][false], 9); + EXPECT_TRUE(res3.valid()) << "Set res3 failed"; + EXPECT_EQ(lua["st"][true], false); + EXPECT_EQ(lua["st"][false], 9); } TEST(sharedTable, multipleStates) { @@ -82,9 +82,9 @@ cats.sparky = false cats.wow = 3 )"); - ASSERT_EQ(lua2["dogs"]["fluffy"], std::string("gav")); - ASSERT_EQ(lua2["dogs"]["sparky"], false); - ASSERT_EQ(lua2["dogs"]["wow"], 3); + EXPECT_EQ(lua2["dogs"]["fluffy"], std::string("gav")); + EXPECT_EQ(lua2["dogs"]["sparky"], false); + EXPECT_EQ(lua2["dogs"]["wow"], 3); } TEST(sharedTable, multipleThreads) { @@ -126,9 +126,9 @@ st.thr = true)"); for(auto& thread : threads) { thread.join(); } - ASSERT_EQ(lua["st"]["fst"], true); - ASSERT_EQ(lua["st"]["snd"], true); - ASSERT_EQ(lua["st"]["thr"], true); + EXPECT_EQ(lua["st"]["fst"], true); + EXPECT_EQ(lua["st"]["snd"], true); + EXPECT_EQ(lua["st"]["thr"], true); } TEST(sharedTable, playingWithSharedTables) { @@ -146,8 +146,8 @@ st1.proxy.value = true recursive.next = recursive recursive.val = "yes" )"); - ASSERT_EQ(lua["st2"]["value"], true); - ASSERT_EQ(lua["recursive"]["next"]["next"]["next"]["val"], std::string("yes")); + EXPECT_EQ(lua["st2"]["value"], true); + EXPECT_EQ(lua["recursive"]["next"]["next"]["next"]["val"], std::string("yes")); } TEST(sharedTable, playingWithFunctions) { @@ -166,7 +166,7 @@ st.fn() )"); sol::function sf = lua["st"]["fn"]; - ASSERT_TRUE((bool)sf()); + EXPECT_TRUE((bool)sf()); sol::state lua2; bootstrapState(lua2); @@ -180,7 +180,7 @@ end sol::function sf2 = lua["st"]["fn2"]; - ASSERT_EQ(sf2(std::string("SUCCESS")).get(), std::string("*SUCCESS*")); + EXPECT_EQ(sf2(std::string("SUCCESS")).get(), std::string("*SUCCESS*")); } TEST(sharedTable, playingWithTables) { @@ -207,15 +207,15 @@ recursive.val = "recursive" st.recursive = recursive )"); - ASSERT_TRUE(res.valid()); - ASSERT_EQ(lua["st"]["person"]["name"], std::string("John Doe")); - ASSERT_EQ(lua["st"]["person"]["age"], 25); - ASSERT_EQ(lua["st"]["pet"]["type"], std::string("cat")); - ASSERT_EQ(lua["st"]["pet"]["name"], std::string("Tomas")); - ASSERT_EQ(lua["st"]["pet"]["real"], std::string("Яша")); - ASSERT_EQ(lua["st"]["pet"]["spec"]["colour"], std::string("grey")); - ASSERT_EQ(lua["st"]["pet"]["spec"]["legs"], 4); - ASSERT_EQ(lua["st"]["recursive"]["prev"]["next"]["next"]["val"], std::string("recursive")); + EXPECT_TRUE(res.valid()); + EXPECT_EQ(lua["st"]["person"]["name"], std::string("John Doe")); + EXPECT_EQ(lua["st"]["person"]["age"], 25); + EXPECT_EQ(lua["st"]["pet"]["type"], std::string("cat")); + EXPECT_EQ(lua["st"]["pet"]["name"], std::string("Tomas")); + EXPECT_EQ(lua["st"]["pet"]["real"], std::string("Яша")); + EXPECT_EQ(lua["st"]["pet"]["spec"]["colour"], std::string("grey")); + EXPECT_EQ(lua["st"]["pet"]["spec"]["legs"], 4); + EXPECT_EQ(lua["st"]["recursive"]["prev"]["next"]["next"]["val"], std::string("recursive")); defaultPool().clear(); } @@ -233,16 +233,16 @@ for i = 1, 1000000 do end )"); - ASSERT_TRUE(res1.valid()); - ASSERT_TRUE(st.size() == 1'000'000); + EXPECT_TRUE(res1.valid()); + EXPECT_TRUE(st.size() == 1'000'000); auto res2 = lua.script(R"( for i = 1000000, 1, -1 do st[i] = nil end )"); - ASSERT_TRUE(res2.valid()); - ASSERT_TRUE(st.size() == 0); + EXPECT_TRUE(res2.valid()); + EXPECT_TRUE(st.size() == 0); } TEST(sharedTable, stressWithThreads) { @@ -272,6 +272,6 @@ TEST(sharedTable, stressWithThreads) { bootstrapState(lua); lua["st"] = &st; for(size_t i = 0; i < threadCount; i++) { - ASSERT_TRUE(lua["st"][i] == 100'001) << (double)lua["st"][i] << std::endl; + EXPECT_TRUE(lua["st"][i] == 100'001) << (double)lua["st"][i] << std::endl; } }