#include #include "rbx/test/DataModelFixture.h" #include "script/ScriptContext.h" #include "script/Script.h" using namespace RBX; LOGGROUP(LuaScriptTimeoutSeconds) void AssertScriptIsTrue(DataModel& dataModel, const char* script) { ScriptContext* scriptContext = ServiceProvider::create(&dataModel); RBX::Reflection::Variant result = scriptContext->executeInNewThread(RBX::Security::GameScript_, ProtectedString::fromTestSource(script), "test", RBX::Reflection::Tuple())->at(0); BOOST_CHECK(result.convert()); } // A sandboxed thread attempts (and fails) to hack the global wait() function void HackWait(DataModel& dataModel, const char* waitHack) { ScriptContext* scriptContext = ServiceProvider::create(&dataModel); // First script tries to modify the environment scriptContext->executeInNewThread(RBX::Security::GameScript_, ProtectedString::fromTestSource(waitHack), "test", RBX::Reflection::Tuple()); // The second script should use the original meaning of "wait" because RBX::Security::GameScript_ is sandboxed RBX::Reflection::Variant result = scriptContext->executeInNewThread(RBX::Security::GameScript_, ProtectedString::fromTestSource("return type(wait) == 'function'"), "test", RBX::Reflection::Tuple())->at(0); BOOST_CHECK(result.convert()); } BOOST_FIXTURE_TEST_SUITE(LuaSandbox, DataModelFixture) BOOST_AUTO_TEST_CASE(Hack_getfenv) { DataModel::LegacyLock lock(dataModel, DataModelJob::Write); HackWait(*dataModel, "getfenv(0).wait = 'hacko!'"); // This was a hack that a user created around 8/13/10 HackWait(*dataModel, "_G = getmetatable(getfenv(1)).__index _G._G = _G _G.wait = 'Hacko'"); } BOOST_AUTO_TEST_CASE(HackGlobal) { DataModel::LegacyLock lock(dataModel, DataModelJob::Write); HackWait(*dataModel, "_G.wait = 'hacko!'"); } BOOST_AUTO_TEST_CASE(HackMathLibrary) { DataModel::LegacyLock lock(dataModel, DataModelJob::Write); AssertScriptIsTrue(*dataModel, "b = pcall(function() rawset(math, 'sin', 'hacko!') end) return not b"); AssertScriptIsTrue(*dataModel, "return getmetatable(math) == nil"); } BOOST_AUTO_TEST_CASE(HackStringMetatable) { DataModel::LegacyLock lock(dataModel, DataModelJob::Write); AssertScriptIsTrue(*dataModel, "return getmetatable('') == 'The metatable is locked'"); } static void testLuaTimeoutLuaSetting(shared_ptr dataModel) { RBX::Time start; shared_ptr