You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Issue #1074 introduced a new customization point to handle checked access. This is currently done only for "real" function arguments, and not for "implicit" argument like the this pointer when calling a member function. The following code illustrates the problem:
#include<sol/sol.hpp>
#include<memory>
#include<iostream>// Create a user classstructfoo {
int value;
foo(int v) : value(v) {}
~foo() { value = 0; }
voidbar() { std::cout << value << std::endl; }
};
// Register customization points to sol to handle weak pointernamespacesol {
template<typename T>
structunique_usertype_traits<std::weak_ptr<T>> {
static T* get(lua_State*, const std::weak_ptr<T>& ptr) noexcept {
return ptr.lock().get();
}
staticboolis_null(lua_State*, const std::weak_ptr<T>& ptr) noexcept {
return ptr.expired();
}
};
}
template<typename T>
voidsol_lua_check_access(sol::types<T>, lua_State* L, int index, sol::stack::record& tracking) {
sol::optional<std::weak_ptr<T>&> maybe_checked =
sol::stack::check_get<std::weak_ptr<T>&>(L, index, sol::no_panic, tracking);
if (!maybe_checked.has_value()) {
return;
}
if (maybe_checked->expired()) {
// We want to throw if the pointer has expiredthrowstd::runtime_error("object has been deleted");
}
}
intmain() {
sol::state lua;
// Register our user typeauto foo_type = lua.new_usertype<foo>("Foo");
foo_type.set_function("bar", &foo::bar);
// Create an object and give Lua an observer to it
std::shared_ptr<foo> owner = std::make_shared<foo>(42);
lua["observer"] = std::weak_ptr<foo>(owner);
// The observer works as expected
lua.do_string("observer:bar()");
// Reset the owner, so the observed object becomes invalid
owner.reset();
// We expect this to throw now; it does not! The call goes through.
lua.do_string("observer:bar()");
}
Compiled with g++ -std=c++17 test.cpp -o test -I"." -I"/usr/include/lua5.2/" -llua5.2
I traced it down to lua_call_wrapper::call using sol::check_get() to fetch the this pointer. Function arguments use stack_detail::check_get_arg(), which is the only place in which the new customization point is used. Therefore, this does not go through this check.
I fixed this by adding the following just before the call to sol::check_get() (call.hpp:486):
I assume there are quite a few other places where this should be done, to cover all kinds of wrappers. Perhaps this is best added inside sol::check_get() to avoid duplication? I'm not sure why this was added only to stack_detail::check_get_arg() in the first place.
The text was updated successfully, but these errors were encountered:
FYI this cschreib@f01daeb is how I fixed it on a fork, but I'm not sure this is 100% correct. It also required my custom sol_lua_check_access() to support T and T*:
template<typename T>
voidsol_lua_check_access(sol::types<T>, lua_State* L, int index, sol::stack::record& tracking) {
using ObjectType = std::remove_pointer_t<T>;
sol::optional<std::weak_ptr<ObjectType>&> maybe_checked =
sol::stack::check_get<std::weak_ptr<ObjectType>&>(L, index, sol::no_panic, tracking);
if (!maybe_checked.has_value()) {
return;
}
if (maybe_checked->expired()) {
// We want to throw if the pointer has expiredthrowstd::runtime_error("object has been deleted");
}
}
I tried just adding the sol_lua_check_access customization to sol::check_get(), but that created a circular dependency (need to call sol::check_get() to get the pointer to check if it is valid). So I take it sol::check_get() is too low level for this.
Just want to say that I've run into the very same issue!
According to #1074 (comment)sol_lua_check_accessshould also be called for member function calls (and also member variable access), so this really looks like a bug.
BTW, I could not find any official documentation for the sol_lua_check_access customization point.
Issue #1074 introduced a new customization point to handle checked access. This is currently done only for "real" function arguments, and not for "implicit" argument like the
this
pointer when calling a member function. The following code illustrates the problem:Compiled with
g++ -std=c++17 test.cpp -o test -I"." -I"/usr/include/lua5.2/" -llua5.2
I traced it down to
lua_call_wrapper::call
usingsol::check_get()
to fetch thethis
pointer. Function arguments usestack_detail::check_get_arg()
, which is the only place in which the new customization point is used. Therefore,this
does not go through this check.I fixed this by adding the following just before the call to
sol::check_get()
(call.hpp:486):I assume there are quite a few other places where this should be done, to cover all kinds of wrappers. Perhaps this is best added inside
sol::check_get()
to avoid duplication? I'm not sure why this was added only tostack_detail::check_get_arg()
in the first place.The text was updated successfully, but these errors were encountered: