Version in base suite: 8.0.2-3 Base version: redis_8.0.2-3 Target version: redis_8.0.2-3+deb13u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/r/redis/redis_8.0.2-3.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/r/redis/redis_8.0.2-3+deb13u1.dsc changelog | 6 patches/0008-CVE-2025-49844.patch | 26 +++ patches/0009-CVE-2025-46819.patch | 158 +++++++++++++++++++++++ patches/0010-CVE-2025-46818.patch | 253 ++++++++++++++++++++++++++++++++++++++ patches/0011-CVE-2025-46817.patch | 86 ++++++++++++ patches/series | 4 6 files changed, 533 insertions(+) gpgv: Signature made Tue Oct 7 19:24:57 2025 UTC gpgv: using RSA key B6E62F3D12AC38495C0DA90510C293B6C37C4E36 gpgv: Note: signatures using the SHA1 algorithm are rejected gpgv: Can't check signature: Bad public key dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmp8l7c7lyn/redis_8.0.2-3+deb13u1.dsc: no acceptable signature found diff -Nru redis-8.0.2/debian/changelog redis-8.0.2/debian/changelog --- redis-8.0.2/debian/changelog 2025-07-14 16:47:32.000000000 +0000 +++ redis-8.0.2/debian/changelog 2025-10-07 18:00:58.000000000 +0000 @@ -1,3 +1,9 @@ +redis (5:8.0.2-3+deb13u1) trixie-security; urgency=medium + + * CVE-2025-49844 / CVE-2025-46819 / CVE-2025-46818 / CVE-2025-46817 + + -- Moritz Mühlenhoff Tue, 07 Oct 2025 20:00:58 +0200 + redis (5:8.0.2-3) unstable; urgency=medium * Add a patch to re-add "Redis ver. $REDIS_VERSION" output to the LOLWUT diff -Nru redis-8.0.2/debian/patches/0008-CVE-2025-49844.patch redis-8.0.2/debian/patches/0008-CVE-2025-49844.patch --- redis-8.0.2/debian/patches/0008-CVE-2025-49844.patch 1970-01-01 00:00:00.000000000 +0000 +++ redis-8.0.2/debian/patches/0008-CVE-2025-49844.patch 2025-10-07 17:54:52.000000000 +0000 @@ -0,0 +1,26 @@ +From d5728cb5795c966c5b5b1e0f0ac576a7e69af539 Mon Sep 17 00:00:00 2001 +From: Mincho Paskalev +Date: Mon, 23 Jun 2025 11:41:37 +0300 +Subject: [PATCH] Lua script may lead to remote code execution (CVE-2025-49844) + +--- redis-8.0.2.orig/deps/lua/src/lparser.c ++++ redis-8.0.2/deps/lua/src/lparser.c +@@ -384,13 +384,17 @@ Proto *luaY_parser (lua_State *L, ZIO *z + struct LexState lexstate; + struct FuncState funcstate; + lexstate.buff = buff; +- luaX_setinput(L, &lexstate, z, luaS_new(L, name)); ++ TString *tname = luaS_new(L, name); ++ setsvalue2s(L, L->top, tname); ++ incr_top(L); ++ luaX_setinput(L, &lexstate, z, tname); + open_func(&lexstate, &funcstate); + funcstate.f->is_vararg = VARARG_ISVARARG; /* main func. is always vararg */ + luaX_next(&lexstate); /* read first token */ + chunk(&lexstate); + check(&lexstate, TK_EOS); + close_func(&lexstate); ++ --L->top; + lua_assert(funcstate.prev == NULL); + lua_assert(funcstate.f->nups == 0); + lua_assert(lexstate.fs == NULL); diff -Nru redis-8.0.2/debian/patches/0009-CVE-2025-46819.patch redis-8.0.2/debian/patches/0009-CVE-2025-46819.patch --- redis-8.0.2/debian/patches/0009-CVE-2025-46819.patch 1970-01-01 00:00:00.000000000 +0000 +++ redis-8.0.2/debian/patches/0009-CVE-2025-46819.patch 2025-10-07 17:57:25.000000000 +0000 @@ -0,0 +1,158 @@ +From 3a1624da2449ac3dbfc4bdaed43adf77a0b7bfba Mon Sep 17 00:00:00 2001 +From: Ozan Tezcan +Date: Mon, 23 Jun 2025 12:11:31 +0300 +Subject: [PATCH] LUA out-of-bound read (CVE-2025-46819) + +--- redis-8.0.2.orig/deps/lua/src/llex.c ++++ redis-8.0.2/deps/lua/src/llex.c +@@ -138,6 +138,7 @@ static void inclinenumber (LexState *ls) + + + void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source) { ++ ls->t.token = 0; + ls->decpoint = '.'; + ls->L = L; + ls->lookahead.token = TK_EOS; /* no look-ahead token */ +@@ -206,9 +207,13 @@ static void read_numeral (LexState *ls, + trydecpoint(ls, seminfo); /* try to update decimal point separator */ + } + +- +-static int skip_sep (LexState *ls) { +- int count = 0; ++/* ++** reads a sequence '[=*[' or ']=*]', leaving the last bracket. ++** If a sequence is well-formed, return its number of '='s + 2; otherwise, ++** return 1 if there is no '='s or 0 otherwise (an unfinished '[==...'). ++*/ ++static size_t skip_sep (LexState *ls) { ++ size_t count = 0; + int s = ls->current; + lua_assert(s == '[' || s == ']'); + save_and_next(ls); +@@ -216,11 +221,13 @@ static int skip_sep (LexState *ls) { + save_and_next(ls); + count++; + } +- return (ls->current == s) ? count : (-count) - 1; ++ return (ls->current == s) ? count + 2 ++ : (count == 0) ? 1 ++ : 0; + } + + +-static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) { ++static void read_long_string (LexState *ls, SemInfo *seminfo, size_t sep) { + int cont = 0; + (void)(cont); /* avoid warnings when `cont' is not used */ + save_and_next(ls); /* skip 2nd `[' */ +@@ -270,8 +277,8 @@ static void read_long_string (LexState * + } + } endloop: + if (seminfo) +- seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep), +- luaZ_bufflen(ls->buff) - 2*(2 + sep)); ++ seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + sep, ++ luaZ_bufflen(ls->buff) - 2 * sep); + } + + +@@ -346,9 +353,9 @@ static int llex (LexState *ls, SemInfo * + /* else is a comment */ + next(ls); + if (ls->current == '[') { +- int sep = skip_sep(ls); ++ size_t sep = skip_sep(ls); + luaZ_resetbuffer(ls->buff); /* `skip_sep' may dirty the buffer */ +- if (sep >= 0) { ++ if (sep >= 2) { + read_long_string(ls, NULL, sep); /* long comment */ + luaZ_resetbuffer(ls->buff); + continue; +@@ -360,13 +367,14 @@ static int llex (LexState *ls, SemInfo * + continue; + } + case '[': { +- int sep = skip_sep(ls); +- if (sep >= 0) { ++ size_t sep = skip_sep(ls); ++ if (sep >= 2) { + read_long_string(ls, seminfo, sep); + return TK_STRING; + } +- else if (sep == -1) return '['; +- else luaX_lexerror(ls, "invalid long string delimiter", TK_STRING); ++ else if (sep == 0) /* '[=...' missing second bracket */ ++ luaX_lexerror(ls, "invalid long string delimiter", TK_STRING); ++ return '['; + } + case '=': { + next(ls); +--- redis-8.0.2.orig/tests/unit/scripting.tcl ++++ redis-8.0.2/tests/unit/scripting.tcl +@@ -341,13 +341,6 @@ start_server {tags {"scripting"}} { + set e + } {*against a key*} + +- test {EVAL - JSON string encoding a string larger than 2GB} { +- run_script { +- local s = string.rep("a", 1024 * 1024 * 1024) +- return #cjson.encode(s..s..s) +- } 0 +- } {3221225474} {large-memory} ;# length includes two double quotes at both ends +- + test {EVAL - JSON numeric decoding} { + # We must return the table as a string because otherwise + # Redis converts floats to ints and we get 0 and 1023 instead +@@ -2422,6 +2415,51 @@ start_server {tags {"scripting"}} { + ] {asdf} + } + ++# start a new server to test the large-memory tests ++start_server {tags {"scripting external:skip large-memory"}} { ++ test {EVAL - JSON string encoding a string larger than 2GB} { ++ run_script { ++ local s = string.rep("a", 1024 * 1024 * 1024) ++ return #cjson.encode(s..s..s) ++ } 0 ++ } {3221225474} ;# length includes two double quotes at both ends ++ ++ test {EVAL - Test long escape sequences for strings} { ++ run_script { ++ -- Generate 1gb '==...==' separator ++ local s = string.rep('=', 1024 * 1024) ++ local t = {} for i=1,1024 do t[i] = s end ++ local sep = table.concat(t) ++ collectgarbage('collect') ++ ++ local code = table.concat({'return [',sep,'[x]',sep,']'}) ++ collectgarbage('collect') ++ ++ -- Load the code and run it. Script will return the string length. ++ -- Escape sequence: [=....=[ to ]=...=] will be ignored ++ -- Actual string is a single character: 'x'. Script will return 1 ++ local func = loadstring(code) ++ return #func() ++ } 0 ++ } {1} ++ ++ test {EVAL - Lua can parse string with too many new lines} { ++ # Create a long string consisting only of newline characters. When Lua ++ # fails to parse a string, it typically includes a snippet like ++ # "... near ..." in the error message to indicate the last recognizable ++ # token. In this test, since the input contains only newlines, there ++ # should be no identifiable token, so the error message should contain ++ # only the actual error, without a near clause. ++ ++ run_script { ++ local s = string.rep('\n', 1024 * 1024) ++ local t = {} for i=1,2048 do t[#t+1] = s end ++ local lines = table.concat(t) ++ local fn, err = loadstring(lines) ++ return err ++ } 0 ++ } {*chunk has too many lines} ++} + test "LUA test trim string as expected" { + # this test may fail if we use different memory allocator than jemalloc, as libc for example may keep the old size on realloc. + if {[string match {*jemalloc*} [s mem_allocator]]} { diff -Nru redis-8.0.2/debian/patches/0010-CVE-2025-46818.patch redis-8.0.2/debian/patches/0010-CVE-2025-46818.patch --- redis-8.0.2/debian/patches/0010-CVE-2025-46818.patch 1970-01-01 00:00:00.000000000 +0000 +++ redis-8.0.2/debian/patches/0010-CVE-2025-46818.patch 2025-10-07 17:59:55.000000000 +0000 @@ -0,0 +1,253 @@ +From 45eac0262028c771b6f5307372814b75f49f7a9e Mon Sep 17 00:00:00 2001 +From: Ozan Tezcan +Date: Mon, 23 Jun 2025 12:10:12 +0300 +Subject: [PATCH] Lua script can be executed in the context of another user + (CVE-2025-46818) + +--- redis-8.0.2.orig/src/config.c ++++ redis-8.0.2/src/config.c +@@ -3114,6 +3114,7 @@ standardConfig static_configs[] = { + createBoolConfig("aof-disable-auto-gc", NULL, MODIFIABLE_CONFIG | HIDDEN_CONFIG, server.aof_disable_auto_gc, 0, NULL, updateAofAutoGCEnabled), + createBoolConfig("replica-ignore-disk-write-errors", NULL, MODIFIABLE_CONFIG, server.repl_ignore_disk_write_error, 0, NULL, NULL), + createBoolConfig("hide-user-data-from-log", NULL, MODIFIABLE_CONFIG, server.hide_user_data_from_log, 0, NULL, NULL), ++ createBoolConfig("lua-enable-deprecated-api", NULL, IMMUTABLE_CONFIG | HIDDEN_CONFIG, server.lua_enable_deprecated_api, 0, NULL, NULL), + + /* String Configs */ + createStringConfig("aclfile", NULL, IMMUTABLE_CONFIG, ALLOW_EMPTY_STRING, server.acl_filename, "", NULL, NULL), +--- redis-8.0.2.orig/src/eval.c ++++ redis-8.0.2/src/eval.c +@@ -252,6 +252,8 @@ void scriptingInit(int setup) { + /* Recursively lock all tables that can be reached from the global table */ + luaSetTableProtectionRecursively(lua); + lua_pop(lua, 1); ++ /* Set metatables of basic types (string, number, nil etc.) readonly. */ ++ luaSetTableProtectionForBasicTypes(lua); + + lctx.lua = lua; + } +--- redis-8.0.2.orig/src/function_lua.c ++++ redis-8.0.2/src/function_lua.c +@@ -495,6 +495,8 @@ int luaEngineInitEngine(void) { + lua_enablereadonlytable(lua_engine_ctx->lua, -1, 1); /* protect the new global table */ + lua_replace(lua_engine_ctx->lua, LUA_GLOBALSINDEX); /* set new global table as the new globals */ + ++ /* Set metatables of basic types (string, number, nil etc.) readonly. */ ++ luaSetTableProtectionForBasicTypes(lua_engine_ctx->lua); + + engine *lua_engine = zmalloc(sizeof(*lua_engine)); + *lua_engine = (engine) { +--- redis-8.0.2.orig/src/script_lua.c ++++ redis-8.0.2/src/script_lua.c +@@ -47,7 +47,6 @@ static char *redis_api_allow_list[] = { + static char *lua_builtins_allow_list[] = { + "xpcall", + "tostring", +- "getfenv", + "setmetatable", + "next", + "assert", +@@ -68,15 +67,16 @@ static char *lua_builtins_allow_list[] = + "loadstring", + "ipairs", + "_VERSION", +- "setfenv", + "load", + "error", + NULL, + }; + +-/* Lua builtins which are not documented on the Lua documentation */ +-static char *lua_builtins_not_documented_allow_list[] = { ++/* Lua builtins which are deprecated for sandboxing concerns */ ++static char *lua_builtins_deprecated[] = { + "newproxy", ++ "setfenv", ++ "getfenv", + NULL, + }; + +@@ -98,7 +98,6 @@ static char **allow_lists[] = { + libraries_allow_list, + redis_api_allow_list, + lua_builtins_allow_list, +- lua_builtins_not_documented_allow_list, + lua_builtins_removed_after_initialization_allow_list, + NULL, + }; +@@ -1301,7 +1300,22 @@ static int luaNewIndexAllowList(lua_Stat + break; + } + } +- if (!*allow_l) { ++ ++ int allowed = (*allow_l != NULL); ++ /* If not explicitly allowed, check if it's a deprecated function. If so, ++ * allow it only if 'lua_enable_deprecated_api' config is enabled. */ ++ int deprecated = 0; ++ if (!allowed) { ++ char **c = lua_builtins_deprecated; ++ for (; *c; ++c) { ++ if (strcmp(*c, variable_name) == 0) { ++ deprecated = 1; ++ allowed = server.lua_enable_deprecated_api ? 1 : 0; ++ break; ++ } ++ } ++ } ++ if (!allowed) { + /* Search the value on the back list, if its there we know that it was removed + * on purpose and there is no need to print a warning. */ + char **c = deny_list; +@@ -1310,7 +1324,7 @@ static int luaNewIndexAllowList(lua_Stat + break; + } + } +- if (!*c) { ++ if (!*c && !deprecated) { + serverLog(LL_WARNING, "A key '%s' was added to Lua globals which is not on the globals allow list nor listed on the deny list.", variable_name); + } + } else { +@@ -1362,6 +1376,37 @@ void luaSetTableProtectionRecursively(lu + } + } + ++/* Set the readonly flag on the metatable of basic types (string, nil etc.) */ ++void luaSetTableProtectionForBasicTypes(lua_State *lua) { ++ static const int types[] = { ++ LUA_TSTRING, ++ LUA_TNUMBER, ++ LUA_TBOOLEAN, ++ LUA_TNIL, ++ LUA_TFUNCTION, ++ LUA_TTHREAD, ++ LUA_TLIGHTUSERDATA ++ }; ++ ++ for (size_t i = 0; i < sizeof(types) / sizeof(types[0]); i++) { ++ /* Push a dummy value of the type to get its metatable */ ++ switch (types[i]) { ++ case LUA_TSTRING: lua_pushstring(lua, ""); break; ++ case LUA_TNUMBER: lua_pushnumber(lua, 0); break; ++ case LUA_TBOOLEAN: lua_pushboolean(lua, 0); break; ++ case LUA_TNIL: lua_pushnil(lua); break; ++ case LUA_TFUNCTION: lua_pushcfunction(lua, NULL); break; ++ case LUA_TTHREAD: lua_newthread(lua); break; ++ case LUA_TLIGHTUSERDATA: lua_pushlightuserdata(lua, (void*)lua); break; ++ } ++ if (lua_getmetatable(lua, -1)) { ++ luaSetTableProtectionRecursively(lua); ++ lua_pop(lua, 1); /* pop metatable */ ++ } ++ lua_pop(lua, 1); /* pop dummy value */ ++ } ++} ++ + void luaRegisterVersion(lua_State* lua) { + lua_pushstring(lua,"REDIS_VERSION_NUM"); + lua_pushnumber(lua,REDIS_VERSION_NUM); +--- redis-8.0.2.orig/src/script_lua.h ++++ redis-8.0.2/src/script_lua.h +@@ -51,6 +51,7 @@ void luaRegisterGlobalProtectionFunction + void luaSetErrorMetatable(lua_State *lua); + void luaSetAllowListProtection(lua_State *lua); + void luaSetTableProtectionRecursively(lua_State *lua); ++void luaSetTableProtectionForBasicTypes(lua_State *lua); + void luaRegisterLogFunction(lua_State* lua); + void luaRegisterVersion(lua_State* lua); + void luaPushErrorBuff(lua_State *lua, sds err_buff); +--- redis-8.0.2.orig/src/server.h ++++ redis-8.0.2/src/server.h +@@ -2194,6 +2194,7 @@ struct redisServer { + mstime_t busy_reply_threshold; /* Script / module timeout in milliseconds */ + int pre_command_oom_state; /* OOM before command (script?) was started */ + int script_disable_deny_script; /* Allow running commands marked "noscript" inside a script. */ ++ int lua_enable_deprecated_api; /* Config to enable deprecated api */ + /* Lazy free */ + int lazyfree_lazy_eviction; + int lazyfree_lazy_expire; +--- redis-8.0.2.orig/tests/unit/scripting.tcl ++++ redis-8.0.2/tests/unit/scripting.tcl +@@ -1078,6 +1078,27 @@ start_server {tags {"scripting"}} { + set _ $e + } {*Attempt to modify a readonly table*} + ++ test "Try trick readonly table on basic types metatable" { ++ # Run the following scripts for basic types. Either getmetatable() ++ # should return nil or the metatable must be readonly. ++ set scripts { ++ {getmetatable(nil).__index = function() return 1 end} ++ {getmetatable('').__index = function() return 1 end} ++ {getmetatable(123.222).__index = function() return 1 end} ++ {getmetatable(true).__index = function() return 1 end} ++ {getmetatable(function() return 1 end).__index = function() return 1 end} ++ {getmetatable(coroutine.create(function() return 1 end)).__index = function() return 1 end} ++ } ++ ++ foreach code $scripts { ++ catch {run_script $code 0} e ++ assert { ++ [string match "*attempt to index a nil value script*" $e] || ++ [string match "*Attempt to modify a readonly table*" $e] ++ } ++ } ++ } ++ + test "Test loadfile are not available" { + catch { + run_script { +@@ -1106,6 +1127,55 @@ start_server {tags {"scripting"}} { + } {*Script attempted to access nonexistent global variable 'print'*} + } + ++# Start a new server to test lua-enable-deprecated-api config ++foreach enabled {no yes} { ++start_server [subst {tags {"scripting external:skip"} overrides {lua-enable-deprecated-api $enabled}}] { ++ test "Test setfenv availability lua-enable-deprecated-api=$enabled" { ++ catch { ++ run_script { ++ local f = function() return 1 end ++ setfenv(f, {}) ++ return 0 ++ } 0 ++ } e ++ if {$enabled} { ++ assert_equal $e 0 ++ } else { ++ assert_match {*Script attempted to access nonexistent global variable 'setfenv'*} $e ++ } ++ } ++ ++ test "Test getfenv availability lua-enable-deprecated-api=$enabled" { ++ catch { ++ run_script { ++ local f = function() return 1 end ++ getfenv(f) ++ return 0 ++ } 0 ++ } e ++ if {$enabled} { ++ assert_equal $e 0 ++ } else { ++ assert_match {*Script attempted to access nonexistent global variable 'getfenv'*} $e ++ } ++ } ++ ++ test "Test newproxy availability lua-enable-deprecated-api=$enabled" { ++ catch { ++ run_script { ++ getmetatable(newproxy(true)).__gc = function() return 1 end ++ return 0 ++ } 0 ++ } e ++ if {$enabled} { ++ assert_equal $e 0 ++ } else { ++ assert_match {*Script attempted to access nonexistent global variable 'newproxy'*} $e ++ } ++ } ++} ++} ++ + # Start a new server since the last test in this stanza will kill the + # instance at all. + start_server {tags {"scripting"}} { diff -Nru redis-8.0.2/debian/patches/0011-CVE-2025-46817.patch redis-8.0.2/debian/patches/0011-CVE-2025-46817.patch --- redis-8.0.2/debian/patches/0011-CVE-2025-46817.patch 1970-01-01 00:00:00.000000000 +0000 +++ redis-8.0.2/debian/patches/0011-CVE-2025-46817.patch 2025-10-07 18:00:48.000000000 +0000 @@ -0,0 +1,86 @@ +From fc9abc775e308374f667fdf3e723ef4b7eb0e3ca Mon Sep 17 00:00:00 2001 +From: Ozan Tezcan +Date: Mon, 23 Jun 2025 13:33:00 +0300 +Subject: [PATCH] Lua script may lead to integer overflow and potential RCE + (CVE-2025-46817) + +--- redis-8.0.2.orig/deps/lua/src/lbaselib.c ++++ redis-8.0.2/deps/lua/src/lbaselib.c +@@ -340,13 +340,14 @@ static int luaB_assert (lua_State *L) { + + + static int luaB_unpack (lua_State *L) { +- int i, e, n; ++ int i, e; ++ unsigned int n; + luaL_checktype(L, 1, LUA_TTABLE); + i = luaL_optint(L, 2, 1); + e = luaL_opt(L, luaL_checkint, 3, luaL_getn(L, 1)); + if (i > e) return 0; /* empty range */ +- n = e - i + 1; /* number of elements */ +- if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arith. overflow */ ++ n = (unsigned int)e - (unsigned int)i; /* number of elements minus 1 */ ++ if (n >= INT_MAX || !lua_checkstack(L, ++n)) + return luaL_error(L, "too many results to unpack"); + lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */ + while (i++ < e) /* push arg[i + 1...e] */ +--- redis-8.0.2.orig/deps/lua/src/ltable.c ++++ redis-8.0.2/deps/lua/src/ltable.c +@@ -434,8 +434,7 @@ static TValue *newkey (lua_State *L, Tab + ** search function for integers + */ + const TValue *luaH_getnum (Table *t, int key) { +- /* (1 <= key && key <= t->sizearray) */ +- if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray)) ++ if (1 <= key && key <= t->sizearray) + return &t->array[key-1]; + else { + lua_Number nk = cast_num(key); +--- redis-8.0.2.orig/tests/unit/scripting.tcl ++++ redis-8.0.2/tests/unit/scripting.tcl +@@ -341,6 +341,45 @@ start_server {tags {"scripting"}} { + set e + } {*against a key*} + ++ test {EVAL - Test table unpack with invalid indexes} { ++ catch {run_script { return {unpack({1,2,3}, -2, 2147483647)} } 0} e ++ assert_match {*too many results to unpack*} $e ++ catch {run_script { return {unpack({1,2,3}, 0, 2147483647)} } 0} e ++ assert_match {*too many results to unpack*} $e ++ catch {run_script { return {unpack({1,2,3}, -2147483648, -2)} } 0} e ++ assert_match {*too many results to unpack*} $e ++ set res [run_script { return {unpack({1,2,3}, -1, -2)} } 0] ++ assert_match {} $res ++ set res [run_script { return {unpack({1,2,3}, 1, -1)} } 0] ++ assert_match {} $res ++ ++ # unpack with range -1 to 5, verify nil indexes ++ set res [run_script { ++ local function unpack_to_list(t, i, j) ++ local n, v = select('#', unpack(t, i, j)), {unpack(t, i, j)} ++ for i = 1, n do v[i] = v[i] or '_NIL_' end ++ v.n = n ++ return v ++ end ++ ++ return unpack_to_list({1,2,3}, -1, 5) ++ } 0] ++ assert_match {_NIL_ _NIL_ 1 2 3 _NIL_ _NIL_} $res ++ ++ # unpack with negative range, verify nil indexes ++ set res [run_script { ++ local function unpack_to_list(t, i, j) ++ local n, v = select('#', unpack(t, i, j)), {unpack(t, i, j)} ++ for i = 1, n do v[i] = v[i] or '_NIL_' end ++ v.n = n ++ return v ++ end ++ ++ return unpack_to_list({1,2,3}, -2147483648, -2147483646) ++ } 0] ++ assert_match {_NIL_ _NIL_ _NIL_} $res ++ } {} ++ + test {EVAL - JSON numeric decoding} { + # We must return the table as a string because otherwise + # Redis converts floats to ints and we get 0 and 1023 instead diff -Nru redis-8.0.2/debian/patches/series redis-8.0.2/debian/patches/series --- redis-8.0.2/debian/patches/series 2025-07-14 16:47:32.000000000 +0000 +++ redis-8.0.2/debian/patches/series 2025-10-07 18:00:35.000000000 +0000 @@ -6,3 +6,7 @@ 0005-CVE-2025-32023.patch 0006-CVE-2025-48367.patch 0007-Add-Redis-ver.-REDIS_VERSION-to-LOLWUT-8-output-as-a.patch +0008-CVE-2025-49844.patch +0009-CVE-2025-46819.patch +0010-CVE-2025-46818.patch +0011-CVE-2025-46817.patch