Skip to content

[fork-ffi] integers: and / or / xor — The bit loops only iterate while the operands are positive (`while a… #90

@Unisay

Description

@Unisay

Package: purescript-lua-integers
File: src/Data/Int/Bits.lua
Function: and / or / xor
Class: semantics Severity: medium

The bit loops only iterate while the operands are positive (while a > 0 and b > 0 / while a > 0 or b > 0), so they produce wrong results for negative inputs, which JS handles as 32-bit two's-complement. Examples: and (-1) 5 is 5 in JS (-1 is all-ones) but the Lua returns 0 because the loop never runs (a <= 0); xor (-1) 0 is -1 in JS but the Lua returns 0. The xor loop also calls a % 2 / b % 2 on negative values, where Lua's floored % gives a different bit decomposition than two's-complement. (The package's bitwise tests do not currently cover negatives, so this is latent, but it diverges from the JS semantics the FFI is meant to implement and is exercised indirectly, e.g. complement composed with and/or.)

Current (Lua):

while a > 0 and b > 0 do ... end   -- (and)
while a > 0 or b > 0 do ... end     -- (or, xor)

Expected: 32-bit two's-complement bitwise results matching JS &, |, ^: and (-1) 5 == 5, xor (-1) 0 == -1.

Proposed fix:

Convert each operand to its unsigned 32-bit representation first (e.g. `if a < 0 then a = a + 0x100000000 end`), iterate a fixed 32 bits, then reinterpret a result >= 0x80000000 as negative (subtract 0x100000000). Simpler: gate this fork on a Lua build with a bit library, or implement a shared signed-32-bit helper.

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