diff --git a/single/sol/sol.hpp b/single/sol/sol.hpp index 0c6e68aa..a7d5b8a3 100644 --- a/single/sol/sol.hpp +++ b/single/sol/sol.hpp @@ -20,8 +20,8 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // This file was generated with a script. -// Generated 2017-05-29 17:06:19.842907 UTC -// This header was generated with sol v2.17.4 (revision fd8e2df) +// Generated 2017-06-03 10:24:17.749249 UTC +// This header was generated with sol v2.17.4 (revision 7168c31) // https://github.com/ThePhD/sol2 #ifndef SOL_SINGLE_INCLUDE_HPP @@ -12291,39 +12291,55 @@ namespace sol { static int real_new_index_call_const(std::true_type, std::true_type, lua_State* L) { auto& src = get_src(L); - auto k = stack::check_get(L, 2); - if (k) { - using std::end; - auto it = detail::find(src, *k); - if (it != end(src)) { - auto& v = *it; - v.second = stack::get(L, 3); - } - else { - src.insert(it, { std::move(*k), stack::get(L, 3) }); - } +#ifdef SOL_CHECK_ARGUMENTS + auto maybek = stack::check_get(L, 2); + if (!maybek) { + return luaL_error(L, "sol: improper key of type %s to a %s", lua_typename(L, static_cast(type_of(L, 2))), detail::demangle().c_str()); + } + K& k = *maybek; +#else + K k = stack::get(L, 2); +#endif + using std::end; + auto it = detail::find(src, k); + if (it != end(src)) { + auto& v = *it; + v.second = stack::get(L, 3); + } + else { + src.insert(it, { std::move(k), stack::get(L, 3) }); } return 0; } static int real_new_index_call_const(std::true_type, std::false_type, lua_State* L) { auto& src = get_src(L); -#ifdef SOL_SAFE_USERTYPE +#ifdef SOL_CHECK_ARGUMENTS auto maybek = stack::check_get(L, 2); if (!maybek) { - return 0; + return luaL_error(L, "sol: improper index of type %s to a %s", lua_typename(L, static_cast(type_of(L, 2))), detail::demangle().c_str()); } - K k = *maybek; + K& k = *maybek; #else K k = stack::get(L, 2); #endif using std::begin; auto it = begin(src); +#ifdef SOL_CHECK_ARGUMENTS + if (k < 1) { + return luaL_error(L, "sol: out of bounds index to a %s", detail::demangle().c_str()); + } +#endif --k; if (k == src.size()) { real_add_call_push(std::integral_constant::value && std::is_copy_constructible::value>(), L, src, 1); return 0; } +#ifdef SOL_CHECK_ARGUMENTS + if (k > src.size()) { + return luaL_error(L, "sol: out of bounds index to a %s", detail::demangle().c_str()); + } +#endif std::advance(it, k); *it = stack::get(L, 3); return 0; diff --git a/sol/container_usertype_metatable.hpp b/sol/container_usertype_metatable.hpp index 42ed7ecc..68d1faf9 100644 --- a/sol/container_usertype_metatable.hpp +++ b/sol/container_usertype_metatable.hpp @@ -225,39 +225,55 @@ namespace sol { static int real_new_index_call_const(std::true_type, std::true_type, lua_State* L) { auto& src = get_src(L); - auto k = stack::check_get(L, 2); - if (k) { - using std::end; - auto it = detail::find(src, *k); - if (it != end(src)) { - auto& v = *it; - v.second = stack::get(L, 3); - } - else { - src.insert(it, { std::move(*k), stack::get(L, 3) }); - } +#ifdef SOL_CHECK_ARGUMENTS + auto maybek = stack::check_get(L, 2); + if (!maybek) { + return luaL_error(L, "sol: improper key of type %s to a %s", lua_typename(L, static_cast(type_of(L, 2))), detail::demangle().c_str()); + } + K& k = *maybek; +#else + K k = stack::get(L, 2); +#endif + using std::end; + auto it = detail::find(src, k); + if (it != end(src)) { + auto& v = *it; + v.second = stack::get(L, 3); + } + else { + src.insert(it, { std::move(k), stack::get(L, 3) }); } return 0; } static int real_new_index_call_const(std::true_type, std::false_type, lua_State* L) { auto& src = get_src(L); -#ifdef SOL_SAFE_USERTYPE +#ifdef SOL_CHECK_ARGUMENTS auto maybek = stack::check_get(L, 2); if (!maybek) { - return 0; + return luaL_error(L, "sol: improper index of type %s to a %s", lua_typename(L, static_cast(type_of(L, 2))), detail::demangle().c_str()); } - K k = *maybek; + K& k = *maybek; #else K k = stack::get(L, 2); #endif using std::begin; auto it = begin(src); +#ifdef SOL_CHECK_ARGUMENTS + if (k < 1) { + return luaL_error(L, "sol: out of bounds index to a %s", detail::demangle().c_str()); + } +#endif --k; if (k == src.size()) { real_add_call_push(std::integral_constant::value && std::is_copy_constructible::value>(), L, src, 1); return 0; } +#ifdef SOL_CHECK_ARGUMENTS + if (k > src.size()) { + return luaL_error(L, "sol: out of bounds index to a %s", detail::demangle().c_str()); + } +#endif std::advance(it, k); *it = stack::get(L, 3); return 0; diff --git a/test_containers.cpp b/test_containers.cpp index a136a90d..990ec690 100644 --- a/test_containers.cpp +++ b/test_containers.cpp @@ -305,12 +305,15 @@ end // Set a global variable called // "arr" to be a vector of 5 lements + lua["c_arr"] = std::array{ { 2, 4, 6, 8, 10 } }; lua["arr"] = std::vector{ 2, 4, 6, 8, 10 }; lua["map"] = std::map{ { 1 , 2 },{ 2, 4 },{ 3, 6 },{ 4, 8 },{ 5, 10 } }; lua["set"] = std::set{ 2, 4, 6, 8, 10 }; + std::array& c_arr = lua["c_arr"]; std::vector& arr = lua["arr"]; std::map& map = lua["map"]; std::set& set = lua["set"]; + REQUIRE(c_arr.size() == 5); REQUIRE(arr.size() == 5); REQUIRE(map.size() == 5); REQUIRE(set.size() == 5); @@ -342,6 +345,32 @@ end REQUIRE(arr.empty()); REQUIRE(map.empty()); REQUIRE(set.empty()); + + REQUIRE_NOTHROW([&]() { + lua.script(R"( +c_arr[1] = 7 +c_arr[2] = 7 +c_arr[3] = 7 +)"); + }()); + SECTION("throw test") { + sol::state tlua; + tlua["c_arr"] = std::array{ { 2, 4, 6, 8, 10 } }; + REQUIRE_THROWS([&]() { + tlua.script(R"( +c_arr[0] = 7 +)"); + }()); + } + SECTION("throw test 2") { + sol::state tlua; + tlua["c_arr"] = std::array{ { 2, 4, 6, 8, 10 } }; + REQUIRE_THROWS([&]() { + tlua.script(R"( +c_arr[-1] = 7 +)"); + }()); + } } TEST_CASE("containers/usertype-transparency", "Make sure containers pass their arguments through transparently and push the results as references, not new values") {