mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
🛠 Guard against environment over-pushing
This commit is contained in:
parent
612b469ad9
commit
0a801ee656
|
@ -62,7 +62,7 @@ namespace sol {
|
||||||
constructor_handler handler {};
|
constructor_handler handler {};
|
||||||
stack::check<env_key_t>(this->lua_state(), -1, handler);
|
stack::check<env_key_t>(this->lua_state(), -1, handler);
|
||||||
#endif // Safety
|
#endif // Safety
|
||||||
lua_pop(this->lua_state(), 2);
|
lua_pop(this->lua_state(), 1);
|
||||||
}
|
}
|
||||||
template <bool b>
|
template <bool b>
|
||||||
basic_environment(env_key_t, const basic_reference<b>& extraction_target)
|
basic_environment(env_key_t, const basic_reference<b>& extraction_target)
|
||||||
|
@ -71,7 +71,7 @@ namespace sol {
|
||||||
constructor_handler handler {};
|
constructor_handler handler {};
|
||||||
stack::check<env_key_t>(this->lua_state(), -1, handler);
|
stack::check<env_key_t>(this->lua_state(), -1, handler);
|
||||||
#endif // Safety
|
#endif // Safety
|
||||||
lua_pop(this->lua_state(), 2);
|
lua_pop(this->lua_state(), 1);
|
||||||
}
|
}
|
||||||
basic_environment(lua_State* L, int index = -1) : base_t(detail::no_safety, L, index) {
|
basic_environment(lua_State* L, int index = -1) : base_t(detail::no_safety, L, index) {
|
||||||
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
|
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
|
||||||
|
@ -136,11 +136,13 @@ namespace sol {
|
||||||
const char* success = lua_setupvalue(L, target_index, 1);
|
const char* success = lua_setupvalue(L, target_index, 1);
|
||||||
if (success == nullptr) {
|
if (success == nullptr) {
|
||||||
// left things alone on the stack, pop them off
|
// left things alone on the stack, pop them off
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 2);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
lua_pop(L, 1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
lua_pop(L, 1);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -152,6 +154,7 @@ namespace sol {
|
||||||
}
|
}
|
||||||
string_view upvalue_name(maybe_upvalue_name);
|
string_view upvalue_name(maybe_upvalue_name);
|
||||||
if (upvalue_name == "_ENV") {
|
if (upvalue_name == "_ENV") {
|
||||||
|
lua_pop(L, 1);
|
||||||
this->push();
|
this->push();
|
||||||
const char* success = lua_setupvalue(L, target_index, upvalue_index);
|
const char* success = lua_setupvalue(L, target_index, upvalue_index);
|
||||||
if (success == nullptr) {
|
if (success == nullptr) {
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include <sol/usertype_traits.hpp>
|
#include <sol/usertype_traits.hpp>
|
||||||
#include <sol/policies.hpp>
|
#include <sol/policies.hpp>
|
||||||
#include <sol/unicode.hpp>
|
#include <sol/unicode.hpp>
|
||||||
|
#include <sol/assert.hpp>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
@ -41,6 +42,8 @@
|
||||||
#include <variant>
|
#include <variant>
|
||||||
#endif // Can use variant
|
#endif // Can use variant
|
||||||
|
|
||||||
|
#include <sol/debug.hpp>
|
||||||
|
|
||||||
namespace sol { namespace stack {
|
namespace sol { namespace stack {
|
||||||
namespace stack_detail {
|
namespace stack_detail {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -141,7 +144,11 @@ namespace sol { namespace stack {
|
||||||
int push_environment_of(const T& target) {
|
int push_environment_of(const T& target) {
|
||||||
lua_State* target_L = target.lua_state();
|
lua_State* target_L = target.lua_state();
|
||||||
int target_index = absolute_index(target_L, -target.push());
|
int target_index = absolute_index(target_L, -target.push());
|
||||||
return push_environment_of(target_L, target_index);
|
int env_count = push_environment_of(target_L, target_index);
|
||||||
|
sol_c_assert(env_count == 1);
|
||||||
|
lua_rotate(target_L, target_index, 1);
|
||||||
|
lua_pop(target_L, 1);
|
||||||
|
return env_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -316,7 +323,7 @@ namespace sol { namespace stack {
|
||||||
if (static_cast<T>(llround(static_cast<lua_Number>(value))) != value) {
|
if (static_cast<T>(llround(static_cast<lua_Number>(value))) != value) {
|
||||||
#if SOL_IS_OFF(SOL_EXCEPTIONS)
|
#if SOL_IS_OFF(SOL_EXCEPTIONS)
|
||||||
// Is this really worth it?
|
// Is this really worth it?
|
||||||
assert(false && "integer value will be misrepresented in lua");
|
sol_m_assert(false, "integer value will be misrepresented in lua");
|
||||||
lua_pushinteger(L, static_cast<lua_Integer>(value));
|
lua_pushinteger(L, static_cast<lua_Integer>(value));
|
||||||
return 1;
|
return 1;
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -57,12 +57,14 @@ inline namespace sol2_tests_environments_get {
|
||||||
sol::state& lua = *plua;
|
sol::state& lua = *plua;
|
||||||
sol::environment& env_f = *penv_f;
|
sol::environment& env_f = *penv_f;
|
||||||
sol::stack_guard luasg(lua);
|
sol::stack_guard luasg(lua);
|
||||||
sol::environment target_env(sol::env_key, target);
|
{
|
||||||
int test_env_f = env_f["test"];
|
sol::environment target_env(sol::env_key, target);
|
||||||
int test_target_env = target_env["test"];
|
int test_env_f = env_f["test"];
|
||||||
REQUIRE(test_env_f == test_target_env);
|
int test_target_env = target_env["test"];
|
||||||
REQUIRE(test_env_f == 31);
|
REQUIRE(test_env_f == test_target_env);
|
||||||
REQUIRE(env_f == target_env);
|
REQUIRE(test_env_f == 31);
|
||||||
|
REQUIRE(env_f == target_env);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -89,20 +91,27 @@ TEST_CASE("environments/get", "Envronments can be taken out of things like Lua f
|
||||||
|
|
||||||
lua.open_libraries(sol::lib::base);
|
lua.open_libraries(sol::lib::base);
|
||||||
|
|
||||||
auto result1 = lua.safe_script("f = function() return test end", sol::script_pass_on_error);
|
{
|
||||||
REQUIRE(result1.valid());
|
auto result1 = lua.safe_script("f = function() return test end", sol::script_pass_on_error);
|
||||||
|
REQUIRE(result1.valid());
|
||||||
|
}
|
||||||
sol::function f = lua["f"];
|
sol::function f = lua["f"];
|
||||||
|
|
||||||
sol::environment env_f(lua, sol::create);
|
sol::environment env_f(lua, sol::create);
|
||||||
env_f["test"] = 31;
|
env_f["test"] = 31;
|
||||||
bool env_f_was_set = sol::set_environment(env_f, f);
|
{
|
||||||
REQUIRE(env_f_was_set);
|
sol::stack_guard luasgf(lua);
|
||||||
|
bool env_f_was_set = sol::set_environment(env_f, f);
|
||||||
|
REQUIRE(env_f_was_set);
|
||||||
|
}
|
||||||
|
|
||||||
int result = f();
|
int result = f();
|
||||||
REQUIRE(result == 31);
|
REQUIRE(result == 31);
|
||||||
|
|
||||||
auto result2 = lua.safe_script("g = function() test = 5 end", sol::script_pass_on_error);
|
{
|
||||||
REQUIRE(result2.valid());
|
auto result2 = lua.safe_script("g = function() test = 5 end", sol::script_pass_on_error);
|
||||||
|
REQUIRE(result2.valid());
|
||||||
|
}
|
||||||
sol::function g = lua["g"];
|
sol::function g = lua["g"];
|
||||||
sol::environment env_g(lua, sol::create);
|
sol::environment env_g(lua, sol::create);
|
||||||
bool env_g_was_set = env_g.set_on(g);
|
bool env_g_was_set = env_g.set_on(g);
|
||||||
|
@ -116,17 +125,21 @@ TEST_CASE("environments/get", "Envronments can be taken out of things like Lua f
|
||||||
sol::object global_test = lua["test"];
|
sol::object global_test = lua["test"];
|
||||||
REQUIRE(!global_test.valid());
|
REQUIRE(!global_test.valid());
|
||||||
|
|
||||||
auto result3 = lua.safe_script("h = function() end", sol::script_pass_on_error);
|
{
|
||||||
REQUIRE(result3.valid());
|
auto result3 = lua.safe_script("h = function() end", sol::script_pass_on_error);
|
||||||
|
REQUIRE(result3.valid());
|
||||||
|
}
|
||||||
|
|
||||||
lua.set_function("check_f_env", check_f_env(lua, env_f));
|
lua.set_function("check_f_env", check_f_env(lua, env_f));
|
||||||
lua.set_function("check_g_env", check_g_env(lua, env_g));
|
lua.set_function("check_g_env", check_g_env(lua, env_g));
|
||||||
lua.set_function("check_h_env", check_h_env(lua));
|
lua.set_function("check_h_env", check_h_env(lua));
|
||||||
|
|
||||||
auto checkf = lua.safe_script("check_f_env(f)", sol::script_pass_on_error);
|
{
|
||||||
REQUIRE(checkf.valid());
|
auto checkf = lua.safe_script("check_f_env(f)", sol::script_pass_on_error);
|
||||||
auto checkg = lua.safe_script("check_g_env(g)", sol::script_pass_on_error);
|
REQUIRE(checkf.valid());
|
||||||
REQUIRE(checkg.valid());
|
auto checkg = lua.safe_script("check_g_env(g)", sol::script_pass_on_error);
|
||||||
auto checkh = lua.safe_script("check_h_env(h)", sol::script_pass_on_error);
|
REQUIRE(checkg.valid());
|
||||||
REQUIRE(checkh.valid());
|
auto checkh = lua.safe_script("check_h_env(h)", sol::script_pass_on_error);
|
||||||
|
REQUIRE(checkh.valid());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,15 +44,21 @@ TEST_CASE("environments/this_environment", "test various situations of pulling o
|
||||||
lua["x"] = 5;
|
lua["x"] = 5;
|
||||||
e["x"] = 20;
|
e["x"] = 20;
|
||||||
SECTION("from Lua script") {
|
SECTION("from Lua script") {
|
||||||
auto result1 = lua.safe_script(code, e, sol::script_pass_on_error);
|
int value = 0;
|
||||||
REQUIRE(result1.valid());
|
{
|
||||||
int value = result1;
|
auto result1 = lua.safe_script(code, e, sol::script_pass_on_error);
|
||||||
|
REQUIRE(result1.valid());
|
||||||
|
value = result1;
|
||||||
|
}
|
||||||
REQUIRE(value == 30);
|
REQUIRE(value == 30);
|
||||||
}
|
}
|
||||||
SECTION("from C++") {
|
SECTION("from C++") {
|
||||||
sol::function f = lua["f"];
|
sol::function f = lua["f"];
|
||||||
bool env_set = e.set_on(f);
|
{
|
||||||
REQUIRE(env_set);
|
sol::stack_guard luasg_env(lua);
|
||||||
|
bool env_set = e.set_on(f);
|
||||||
|
REQUIRE(env_set);
|
||||||
|
}
|
||||||
int value = f(10);
|
int value = f(10);
|
||||||
REQUIRE(value == 30);
|
REQUIRE(value == 30);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user