File bsc1198952-1.patch of Package redis.27450

From 13c1e1f2986adcd8788f464a1931cdfe744f15f9 Mon Sep 17 00:00:00 2001
From: meir <meir@redis.com>
Date: Sun, 6 Feb 2022 13:43:18 +0200
Subject: [PATCH] Added support for Lua readonly tables.

The new feature can be turned off and on using the new `lua_enablereadonlytable` Lua API.

(cherry picked from commit 92b5098b87e2d0880a530899119524bf1dfbc332)
---
 deps/lua/src/lapi.c    | 14 ++++++++++++++
 deps/lua/src/ldebug.c  |  1 -
 deps/lua/src/lobject.h |  3 ++-
 deps/lua/src/ltable.c  |  1 +
 deps/lua/src/lua.h     |  2 ++
 deps/lua/src/lvm.c     |  2 ++
 6 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/deps/lua/src/lapi.c b/deps/lua/src/lapi.c
index 5d5145d2ebad..1a9455629450 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 50ad3d38035e..4940e65a6c8f 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 f1e447ef3ba8..10e46b178022 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 ec84f4fabc51..f75fe19fe39a 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 a4b73e743ede..e478d14c02e3 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 e0a0cd85219d..5cd313b5e3a0 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? */
openSUSE Build Service is sponsored by