Skip to content

Commit 4a1cde6

Browse files
authored
Fix userdata nil bug (#305)
* Fix userdata nil bug * Add test to verify userdata nil bug
1 parent c19931b commit 4a1cde6

File tree

3 files changed

+135
-1
lines changed

3 files changed

+135
-1
lines changed

Source/LuaBridge/detail/Userdata.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -575,7 +575,11 @@ struct StackHelper<T, false>
575575

576576
static inline T const& get(lua_State* L, int index)
577577
{
578-
return *Userdata::get<T>(L, index, true);
578+
const T* const t = Userdata::get<T>(L, index, true);
579+
580+
if (!t)
581+
luaL_error(L, "nil passed instead of object");
582+
return *t;
579583
}
580584
};
581585

Tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ set(LUABRIDGE_TEST_SOURCE_FILES
1818
Source/TestTypes.h
1919
Source/TestsMain.cpp
2020
Source/UnorderedMapTests.cpp
21+
Source/UserdataTests.cpp
2122
Source/VectorTests.cpp
2223
)
2324

Tests/Source/UserdataTests.cpp

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
// https://github.com/vinniefalco/LuaBridge
2+
// Copyright 2022, Stefan Frings
3+
// SPDX-License-Identifier: MIT
4+
5+
#include "TestBase.h"
6+
7+
#include "LuaBridge/LuaBridge.h"
8+
9+
class TestClass
10+
{
11+
public:
12+
explicit inline TestClass(int i) : m_i(i) {}
13+
14+
inline int get() const { return m_i; }
15+
16+
private:
17+
int m_i;
18+
};
19+
20+
int testFunctionObject(TestClass object)
21+
{
22+
return object.get();
23+
}
24+
25+
int testFunctionObjectConst(const TestClass object)
26+
{
27+
return object.get();
28+
}
29+
30+
int testFunctionRef(TestClass& object)
31+
{
32+
return object.get();
33+
}
34+
35+
int testFunctionRefConst(const TestClass& object)
36+
{
37+
return object.get();
38+
}
39+
40+
struct UserDataTest : TestBase
41+
{
42+
void SetUp() override
43+
{
44+
TestBase::SetUp();
45+
46+
luabridge::getGlobalNamespace(L)
47+
.beginClass<TestClass>("TestClass")
48+
.addConstructor<void (*)(int)>()
49+
.endClass()
50+
.
51+
52+
addFunction("testFunctionObject", testFunctionObject)
53+
.addFunction("testFunctionObjectConst", testFunctionObjectConst)
54+
.addFunction("testFunctionRef", testFunctionRef)
55+
.addFunction("testFunctionRefConst", testFunctionRefConst);
56+
}
57+
};
58+
59+
TEST_F(UserDataTest, Object)
60+
{
61+
runLua("object = TestClass(123)\n"
62+
"result = testFunctionObject(object)");
63+
64+
ASSERT_EQ(result(), 123);
65+
}
66+
67+
TEST_F(UserDataTest, ObjectConst)
68+
{
69+
runLua("object = TestClass(123)\n"
70+
"result = testFunctionObjectConst(object)");
71+
72+
ASSERT_EQ(result(), 123);
73+
}
74+
75+
TEST_F(UserDataTest, Ref)
76+
{
77+
runLua("object = TestClass(123)\n"
78+
"result = testFunctionRef(object)");
79+
80+
ASSERT_EQ(result(), 123);
81+
}
82+
83+
TEST_F(UserDataTest, RefConst)
84+
{
85+
runLua("object = TestClass(123)\n"
86+
"result = testFunctionRefConst(object)");
87+
88+
ASSERT_EQ(result(), 123);
89+
}
90+
91+
TEST_F(UserDataTest, FailNumberObject)
92+
{
93+
ASSERT_THROW(runLua("testFunctionObject(132)");, std::runtime_error);
94+
}
95+
96+
TEST_F(UserDataTest, FailNumberObjectConst)
97+
{
98+
ASSERT_THROW(runLua("testFunctionObjectConst(132)");, std::runtime_error);
99+
}
100+
101+
TEST_F(UserDataTest, FailNumberRef)
102+
{
103+
ASSERT_THROW(runLua("testFunctionRef(132)");, std::runtime_error);
104+
}
105+
106+
TEST_F(UserDataTest, FailNumberRefConst)
107+
{
108+
ASSERT_THROW(runLua("testFunctionRefConst(132)");, std::runtime_error);
109+
}
110+
111+
TEST_F(UserDataTest, FailNilObject)
112+
{
113+
ASSERT_THROW(runLua("testFunctionObject(nil)");, std::runtime_error);
114+
}
115+
116+
TEST_F(UserDataTest, FailNilObjectConst)
117+
{
118+
ASSERT_THROW(runLua("testFunctionObjectConst(nil)");, std::runtime_error);
119+
}
120+
121+
TEST_F(UserDataTest, FailNilRef)
122+
{
123+
ASSERT_THROW(runLua("testFunctionRef(nil)");, std::runtime_error);
124+
}
125+
126+
TEST_F(UserDataTest, FailNilRefConst)
127+
{
128+
ASSERT_THROW(runLua("testFunctionRefConst(nil)");, std::runtime_error);
129+
}

0 commit comments

Comments
 (0)