Skip to content

Commit c9fee1d

Browse files
committed
Incompatible holder types cause crash
1 parent 120e2e2 commit c9fee1d

File tree

2 files changed

+21
-0
lines changed

2 files changed

+21
-0
lines changed

tests/test_smart_ptr.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,17 @@ class unique_ptr_with_addressof_operator {
8585
};
8686
PYBIND11_DECLARE_HOLDER_TYPE(T, unique_ptr_with_addressof_operator<T>);
8787

88+
// Simple custom holder that works like shared_ptr, but has a different memory layout
89+
template <typename T>
90+
class huge_shared_ptr {
91+
uint64_t padding[10];
92+
std::shared_ptr<T> impl;
93+
public:
94+
huge_shared_ptr( ) = default;
95+
huge_shared_ptr(T* p) : impl(p) { }
96+
T* get() const { return impl.get(); }
97+
};
98+
PYBIND11_DECLARE_HOLDER_TYPE(T, huge_shared_ptr<T>);
8899

89100
TEST_SUBMODULE(smart_ptr, m) {
90101

@@ -143,6 +154,10 @@ TEST_SUBMODULE(smart_ptr, m) {
143154
m.def("print_myobject2_2", [](std::shared_ptr<MyObject2> obj) { py::print(obj->toString()); });
144155
m.def("print_myobject2_3", [](const std::shared_ptr<MyObject2> &obj) { py::print(obj->toString()); });
145156
m.def("print_myobject2_4", [](const std::shared_ptr<MyObject2> *obj) { py::print((*obj)->toString()); });
157+
// Using wrong holder type should raise a cast_error at runtime
158+
m.def("make_myobject2_3", []() { return huge_shared_ptr<MyObject2>(new MyObject2(9)); });
159+
m.def("print_myobject2_5", [](const huge_shared_ptr<MyObject2> &obj) { py::print(obj.get()->toString()); });
160+
m.def("print_myobject2_6", [](const huge_shared_ptr<MyObject2> *obj) { py::print(obj->get()->toString()); });
146161

147162
// Object managed by a std::shared_ptr<>, additionally derives from std::enable_shared_from_this<>
148163
class MyObject3 : public std::enable_shared_from_this<MyObject3> {

tests/test_smart_ptr.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ def test_smart_ptr(capture):
5959
m.print_myobject2_3(o)
6060
m.print_myobject2_4(o)
6161
assert capture == "MyObject2[{i}]\n".format(i=i) * 4
62+
with pytest.raises(RuntimeError):
63+
m.print_myobject2_5(o)
64+
with pytest.raises(RuntimeError):
65+
m.print_myobject2_6(o)
66+
with pytest.raises(RuntimeError):
67+
m.make_myobject2_3()
6268

6369
cstats = ConstructorStats.get(m.MyObject2)
6470
assert cstats.alive() == 1

0 commit comments

Comments
 (0)