Package: purescript-lua-arrays
File: src/Data/Array/ST.lua
Function: spliceImpl
Class: semantics Severity: high
JS xs.splice(i, howMany, ...bs) removes howMany elements at index i, inserts bs in their place (in-place mutation of xs, with the array shrinking/growing as needed), and RETURNS the array of removed elements. The Lua version only does move(xs, i + howMany + 1, #xs, i + #bs + 1, xs): it shifts the tail but never inserts the bs values, never shrinks the array when #bs < howMany (leaving stale duplicated trailing elements), and returns the whole mutated xs instead of the removed slice. Confirmed under Lua 5.1: spliceImpl(1, 2, {99}, {10,20,30,40,50}) returned {10,20,40,50,50} (len 5) and the same as the 'removed' value, instead of mutating xs to {10,99,40,50} and returning {20,30}. With insert>remove, spliceImpl(1,1,{8,9},{1,2,3}) gave {1,2,3,3} instead of {1,8,9,3}.
Current (Lua):
spliceImpl = (function(i, howMany, bs, xs) return move(xs, i + howMany + 1, #xs, i + #bs + 1, xs) end)
Expected: Mutate xs by deleting howMany elements at 0-based index i and inserting bs there; return a new array of the removed elements. spliceImpl(1,2,{99},{10,20,30,40,50}) => xs={10,99,40,50}, returns {20,30}.
Proposed fix:
Implement full splice semantics, collecting removed elements, shifting the tail by (#bs - howMany), trimming surplus slots to nil when shrinking, then writing bs into the gap:
spliceImpl = (function(i, howMany, bs, xs)
local n = #xs
local removed = {}
for k = 1, howMany do removed[k] = xs[i + k] end
local nb, delta = #bs, #bs - howMany
if delta > 0 then
for k = n, i + howMany + 1, -1 do xs[k + delta] = xs[k] end
elseif delta < 0 then
for k = i + howMany + 1, n do xs[k + delta] = xs[k] end
for k = n + delta + 1, n do xs[k] = nil end
end
for k = 1, nb do xs[i + k] = bs[k] end
return removed
end)
Verified under Lua 5.1 across remove>insert, insert>remove, and no-op cases.
Found by the FFI audit; reproduced under Lua 5.1.
Package: purescript-lua-arrays
File:
src/Data/Array/ST.luaFunction:
spliceImplClass: semantics Severity: high
JS
xs.splice(i, howMany, ...bs)removeshowManyelements at index i, insertsbsin their place (in-place mutation of xs, with the array shrinking/growing as needed), and RETURNS the array of removed elements. The Lua version only doesmove(xs, i + howMany + 1, #xs, i + #bs + 1, xs): it shifts the tail but never inserts thebsvalues, never shrinks the array when #bs < howMany (leaving stale duplicated trailing elements), and returns the whole mutatedxsinstead of the removed slice. Confirmed under Lua 5.1: spliceImpl(1, 2, {99}, {10,20,30,40,50}) returned {10,20,40,50,50} (len 5) and the same as the 'removed' value, instead of mutating xs to {10,99,40,50} and returning {20,30}. With insert>remove, spliceImpl(1,1,{8,9},{1,2,3}) gave {1,2,3,3} instead of {1,8,9,3}.Current (Lua):
Expected: Mutate xs by deleting howMany elements at 0-based index i and inserting bs there; return a new array of the removed elements. spliceImpl(1,2,{99},{10,20,30,40,50}) => xs={10,99,40,50}, returns {20,30}.
Proposed fix:
Found by the FFI audit; reproduced under Lua 5.1.