summaryrefslogtreecommitdiff
path: root/deps
diff options
context:
space:
mode:
authormeir <meir@redis.com>2022-02-06 13:43:18 +0200
committermeir <meir@redis.com>2022-04-27 00:20:54 +0300
commit8b33d813a3d47d4daeaaef03b7e42a51f6931f79 (patch)
tree80c6a7ec11499b55b698d8e63cd15bb6f4c33fcb /deps
parent81926254586f64fc6a9b393bf9afb0d2eacc5234 (diff)
downloadredis-8b33d813a3d47d4daeaaef03b7e42a51f6931f79.tar.gz
Added support for Lua readonly tables.
The new feature can be turned off and on using the new `lua_enablereadonlytable` Lua API.
Diffstat (limited to 'deps')
-rw-r--r--deps/lua/src/lapi.c14
-rw-r--r--deps/lua/src/ldebug.c1
-rw-r--r--deps/lua/src/lobject.h3
-rw-r--r--deps/lua/src/ltable.c1
-rw-r--r--deps/lua/src/lua.h2
-rw-r--r--deps/lua/src/lvm.c2
6 files changed, 21 insertions, 2 deletions
diff --git a/deps/lua/src/lapi.c b/deps/lua/src/lapi.c
index 5d5145d2e..1a9455629 100644
--- a/deps/lua/src/lapi.c
+++ b/deps/lua/src/lapi.c
@@ -674,6 +674,8 @@ LUA_API void lua_rawset (lua_State *L, int idx) {
api_checknelems(L, 2);
t = index2adr(L, idx);
api_check(L, ttistable(t));
+ if (hvalue(t)->readonly)
+ luaG_runerror(L, "Attempt to modify a readonly table");
setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1);
luaC_barriert(L, hvalue(t), L->top-1);
L->top -= 2;
@@ -687,6 +689,8 @@ LUA_API void lua_rawseti (lua_State *L, int idx, int n) {
api_checknelems(L, 1);
o = index2adr(L, idx);
api_check(L, ttistable(o));
+ if (hvalue(o)->readonly)
+ luaG_runerror(L, "Attempt to modify a readonly table");
setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1);
luaC_barriert(L, hvalue(o), L->top-1);
L->top--;
@@ -709,6 +713,8 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) {
}
switch (ttype(obj)) {
case LUA_TTABLE: {
+ if (hvalue(obj)->readonly)
+ luaG_runerror(L, "Attempt to modify a readonly table");
hvalue(obj)->metatable = mt;
if (mt)
luaC_objbarriert(L, hvalue(obj), mt);
@@ -1085,3 +1091,11 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
return name;
}
+LUA_API void lua_enablereadonlytable (lua_State *L, int objindex, int enabled) {
+ const TValue* o = index2adr(L, objindex);
+ api_check(L, ttistable(o));
+ Table* t = hvalue(o);
+ api_check(L, t != hvalue(registry(L)));
+ t->readonly = enabled;
+}
+
diff --git a/deps/lua/src/ldebug.c b/deps/lua/src/ldebug.c
index 50ad3d380..4940e65a6 100644
--- a/deps/lua/src/ldebug.c
+++ b/deps/lua/src/ldebug.c
@@ -80,7 +80,6 @@ LUA_API int lua_gethookcount (lua_State *L) {
return L->basehookcount;
}
-
LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
int status;
CallInfo *ci;
diff --git a/deps/lua/src/lobject.h b/deps/lua/src/lobject.h
index f1e447ef3..10e46b178 100644
--- a/deps/lua/src/lobject.h
+++ b/deps/lua/src/lobject.h
@@ -337,7 +337,8 @@ typedef struct Node {
typedef struct Table {
CommonHeader;
- lu_byte flags; /* 1<<p means tagmethod(p) is not present */
+ lu_byte flags; /* 1<<p means tagmethod(p) is not present */
+ int readonly;
lu_byte lsizenode; /* log2 of size of `node' array */
struct Table *metatable;
TValue *array; /* array part */
diff --git a/deps/lua/src/ltable.c b/deps/lua/src/ltable.c
index ec84f4fab..f75fe19fe 100644
--- a/deps/lua/src/ltable.c
+++ b/deps/lua/src/ltable.c
@@ -364,6 +364,7 @@ Table *luaH_new (lua_State *L, int narray, int nhash) {
t->array = NULL;
t->sizearray = 0;
t->lsizenode = 0;
+ t->readonly = 0;
t->node = cast(Node *, dummynode);
setarrayvector(L, t, narray);
setnodevector(L, t, nhash);
diff --git a/deps/lua/src/lua.h b/deps/lua/src/lua.h
index a4b73e743..e478d14c0 100644
--- a/deps/lua/src/lua.h
+++ b/deps/lua/src/lua.h
@@ -358,6 +358,8 @@ struct lua_Debug {
int i_ci; /* active function */
};
+LUA_API void lua_enablereadonlytable (lua_State *L, int index, int enabled);
+
/* }====================================================================== */
diff --git a/deps/lua/src/lvm.c b/deps/lua/src/lvm.c
index e0a0cd852..5cd313b5e 100644
--- a/deps/lua/src/lvm.c
+++ b/deps/lua/src/lvm.c
@@ -138,6 +138,8 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
const TValue *tm;
if (ttistable(t)) { /* `t' is a table? */
Table *h = hvalue(t);
+ if (h->readonly)
+ luaG_runerror(L, "Attempt to modify a readonly table");
TValue *oldval = luaH_set(L, h, key); /* do a primitive set */
if (!ttisnil(oldval) || /* result is no nil? */
(tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */