On Sat, Mar 6, 2021 at 10:13 PM Marcel Fabian Krüger <tex@2krueger.de> wrote:
Hi,

Look at the texlua script:

print(sio.readinteger4(string.pack(">i", -1), 1))

It would be expected that this prints "-1", but at least is should print
a number in the range of 4-byte signed integers (-2147483648 -- 2147483647).
Instead it prints -4294967297. The same issue appears with
fio.readinteger4 and [fs]readintegertable(..., 4): Whenever the value is
negative, the returned value is 2^32 lower than expected. (Technically
this only happens if Lua's integer type allows at least 64-bit integers
and the native "int" type has at most 32-bit, but this is the case on
basically any current platform. The cause is code like the following
in the affected C implementations:


  int a = ...;
  int b = ...;
  int c = ...;
  int d = ...;
  if (a >= 0x80)
      lua_pushinteger(L, 0x1000000 * a + 0x10000 * b + 0x100 * c + d - 0x100000000);
  else ...;

Here a, b, c, d are "int", so according to C language rules
"0x1000000 * a + 0x10000 * b + 0x100 * c + d" is evaluated as a (signed)
int. If a>=0x80 then 0x1000000*0x80 is bigger than 2^31 and can
therefore not be represented in a (32-bit) int. Theoretically this
triggers undefined behavior since LuaTeX does not compile with
"-fwrapv" or similar, but on my system it does "the expected thing" and
wraps. Therefore the value is already negative and the subtraction of
0x100000000, which is evaluated in 64bit since the literal can not be
represented in 32bit, leads to the unexpected value.
This can be fixed by making sure that the expression is completely evaluated with
64-bit integers (or whatever integer type Lua uses). A possible patch is
attached.

Best regards,
Marcel
_______________________________________________
dev-luatex mailing list
dev-luatex@ntg.nl
https://mailman.ntg.nl/mailman/listinfo/dev-luatex

confirmed
--
luigi