Skip to content

Commit 002a46c

Browse files
committed
Fix ll.ListReplaceList off-by-one error in SLua
1 parent 19f3d39 commit 002a46c

File tree

2 files changed

+15
-3
lines changed

2 files changed

+15
-3
lines changed

VM/src/lll.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -577,8 +577,9 @@ static int ll_listreplacelist(lua_State *L)
577577
luaL_checktype(L, 1, LUA_TTABLE);
578578
luaL_checktype(L, 2, LUA_TTABLE);
579579
int orig_len = lua_objlen(L, 1);
580+
bool compat_mode = lua_toboolean(L, lua_upvalueindex(1));
580581
// Let llDeleteSubList handle the tricky part.
581-
lua_pushboolean(L, true);
582+
lua_pushboolean(L, compat_mode);
582583
lua_pushcclosurek(L, ll_deletesublist, "DeleteSubList", 1, nullptr);
583584
lua_pushvalue(L, 1);
584585
lua_pushvalue(L, 3);
@@ -593,8 +594,6 @@ static int ll_listreplacelist(lua_State *L)
593594
auto *src_h = hvalue(luaA_toobject(L, 2));
594595
int src_len = luaH_getn(src_h);
595596

596-
bool compat_mode = lua_toboolean(L, lua_upvalueindex(1));
597-
598597
int target = _checkobjectindex(L, orig_len, 3, compat_mode);
599598

600599
LuaTable *cloned_h = nullptr;

tests/conformance/llcompat.lua

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,17 @@ assert(llcompat.List2Float(foo, 1) == 2)
1212
assert(llcompat.List2Float(foo, -1) == 3)
1313
assert(llcompat.List2Integer(foo, 0) == 1)
1414

15+
-- ll.ListReplaceList uses 1-based indices
16+
local t = {"a", "b", "c", "d"}
17+
assert(lljson.encode(ll.ListReplaceList(t, {"x"}, 2, 2)) == '["a","x","c","d"]')
18+
assert(lljson.encode(ll.ListReplaceList(t, {"x", "y"}, 2, 3)) == '["a","x","y","d"]')
19+
assert(lljson.encode(ll.ListReplaceList(t, {"x"}, 1, 1)) == '["x","b","c","d"]')
20+
assert(lljson.encode(ll.ListReplaceList(t, {"x"}, -1, -1)) == '["a","b","c","x"]')
21+
assert(lljson.encode(ll.ListReplaceList(t, {"x"}, 1, -1)) == '["x"]')
22+
23+
-- llcompat.ListReplaceList uses 0-based indices
24+
assert(lljson.encode(llcompat.ListReplaceList(t, {"x"}, 1, 1)) == '["a","x","c","d"]')
25+
assert(lljson.encode(llcompat.ListReplaceList(t, {"x"}, 0, 0)) == '["x","b","c","d"]')
26+
assert(lljson.encode(llcompat.ListReplaceList(t, {"x"}, -1, -1)) == '["a","b","c","x"]')
27+
1528
return 'OK'

0 commit comments

Comments
 (0)