Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Roblox
GitHub Repository: Roblox/luau
Path: blob/master/VM/src/linit.cpp
2725 views
1
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
2
// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details
3
#include "lualib.h"
4
#include "lstate.h"
5
6
#include <stdlib.h>
7
8
LUAU_FASTFLAG(LuauIntegerType)
9
LUAU_FASTFLAG(LuauIntegerLibrary)
10
11
static const luaL_Reg lualibs[] = {
12
{"", luaopen_base},
13
{LUA_COLIBNAME, luaopen_coroutine},
14
{LUA_TABLIBNAME, luaopen_table},
15
{LUA_OSLIBNAME, luaopen_os},
16
{LUA_STRLIBNAME, luaopen_string},
17
{LUA_MATHLIBNAME, luaopen_math},
18
{LUA_DBLIBNAME, luaopen_debug},
19
{LUA_UTF8LIBNAME, luaopen_utf8},
20
{LUA_BITLIBNAME, luaopen_bit32},
21
{LUA_BUFFERLIBNAME, luaopen_buffer},
22
{LUA_VECLIBNAME, luaopen_vector},
23
{LUA_INTLIBNAME, luaopen_integer},
24
{NULL, NULL},
25
};
26
27
static const luaL_Reg lualibs_NOINTEGER[] = {
28
{"", luaopen_base},
29
{LUA_COLIBNAME, luaopen_coroutine},
30
{LUA_TABLIBNAME, luaopen_table},
31
{LUA_OSLIBNAME, luaopen_os},
32
{LUA_STRLIBNAME, luaopen_string},
33
{LUA_MATHLIBNAME, luaopen_math},
34
{LUA_DBLIBNAME, luaopen_debug},
35
{LUA_UTF8LIBNAME, luaopen_utf8},
36
{LUA_BITLIBNAME, luaopen_bit32},
37
{LUA_BUFFERLIBNAME, luaopen_buffer},
38
{LUA_VECLIBNAME, luaopen_vector},
39
{NULL, NULL},
40
};
41
42
void luaL_openlibs(lua_State* L)
43
{
44
const luaL_Reg* lib;
45
if (FFlag::LuauIntegerType && FFlag::LuauIntegerLibrary)
46
lib = lualibs;
47
else
48
lib = lualibs_NOINTEGER;
49
50
for (; lib->func; lib++)
51
{
52
lua_pushcfunction(L, lib->func, NULL);
53
lua_pushstring(L, lib->name);
54
lua_call(L, 1, 0);
55
}
56
}
57
58
void luaL_sandbox(lua_State* L)
59
{
60
// set all libraries to read-only
61
lua_pushnil(L);
62
while (lua_next(L, LUA_GLOBALSINDEX) != 0)
63
{
64
if (lua_istable(L, -1))
65
lua_setreadonly(L, -1, true);
66
67
lua_pop(L, 1);
68
}
69
70
// set all builtin metatables to read-only
71
lua_pushliteral(L, "");
72
if (lua_getmetatable(L, -1))
73
{
74
lua_setreadonly(L, -1, true);
75
lua_pop(L, 2);
76
}
77
else
78
{
79
lua_pop(L, 1);
80
}
81
82
// set globals to readonly and activate safeenv since the env is immutable
83
lua_setreadonly(L, LUA_GLOBALSINDEX, true);
84
lua_setsafeenv(L, LUA_GLOBALSINDEX, true);
85
}
86
87
void luaL_sandboxthread(lua_State* L)
88
{
89
// create new global table that proxies reads to original table
90
lua_newtable(L);
91
92
lua_newtable(L);
93
lua_pushvalue(L, LUA_GLOBALSINDEX);
94
lua_setfield(L, -2, "__index");
95
lua_setreadonly(L, -1, true);
96
97
lua_setmetatable(L, -2);
98
99
// we can set safeenv now although it's important to set it to false if code is loaded twice into the thread
100
lua_replace(L, LUA_GLOBALSINDEX);
101
lua_setsafeenv(L, LUA_GLOBALSINDEX, true);
102
}
103
104
static void* l_alloc(void* ud, void* ptr, size_t osize, size_t nsize)
105
{
106
(void)ud;
107
(void)osize;
108
if (nsize == 0)
109
{
110
free(ptr);
111
return NULL;
112
}
113
else
114
return realloc(ptr, nsize);
115
}
116
117
lua_State* luaL_newstate(void)
118
{
119
return lua_newstate(l_alloc, NULL);
120
}
121
122