Skip to content

[fork-ffi] arrays: unshiftAllImpl — Must prepend as to the front of xs (JS `xs.unshift.apply(xs,… #74

@Unisay

Description

@Unisay

Package: purescript-lua-arrays
File: src/Data/Array/ST.lua
Function: unshiftAllImpl
Class: semantics Severity: high

Must prepend as to the front of xs (JS xs.unshift.apply(xs, as)), shifting existing elements right and growing the array by #as. Instead it does move(as, 1, #as, 1, xs), which copies as over the first #as slots of xs, overwriting existing elements and leaving the rest in place -- it neither shifts nor grows. Confirmed under Lua 5.1: unshiftAllImpl({1,2}, {3,4,5}) produced {1,2,5} (length 3) instead of {1,2,3,4,5} (length 5), and returned 3 instead of 5.

Current (Lua):

unshiftAllImpl = (function(as, xs)
  local r = move(as, 1, #as, 1, xs)
  return #r
end)

Expected: Prepend all of as: xs becomes as ++ old-xs, and the new length (#as + old #xs) is returned. unshiftAllImpl({1,2}, {3,4,5}) must mutate xs to {1,2,3,4,5} and return 5.

Proposed fix:

Shift the existing tail right by #as first, then copy `as` into the front:
  unshiftAllImpl = (function(as, xs)
    local na, nx = #as, #xs
    for i = nx, 1, -1 do xs[i + na] = xs[i] end
    for i = 1, na do xs[i] = as[i] end
    return nx + na
  end)
Verified under Lua 5.1: yields {1,2,3,4,5}, returns 5.

Found by the FFI audit; reproduced under Lua 5.1.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions