lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


2015-04-21 17:32 GMT+02:00 Egor Skriptunoff <egor.skriptunoff@gmail.com>:
> Hi!
>
> An interesting bug has been found in Lua 5.3
>
> t = {[(1<<63)-333] = 0}
> key = next(t) + 0.0
> t[key] = "Lua is great!"
> print(t[key])          --> Lua is great!
> t[0] = "Are you sure?"
> print(t[key])          --> nil
>
> Why Lua is not great anymore?

The manual says:

The indexing of tables follows the definition of raw equality in the
language. The expressions a[i] and a[j] denote the same table element
if and only if i and j are raw equal (that is, equal without
metamethods). In particular, floats with integral values are equal to
their respective integers (e.g., 1.0 == 1). To avoid ambiguities, any
float with integral value used as a key is converted to its respective
integer. For instance, if you write a[2.0] = true, the actual key
inserted into the table will be the integer 2. (On the other hand, 2
and "2" are different Lua values and therefore denote different table
entries.)

Let origkey = 1<<63)-333, which  is a very large integer, but slightly
smaller than math.maxinteger.

"key" is a float with integral value, but that integral value is not
origkey, but math.maxinteger. In a floating-point comparison, it tests
equal to origkey,
though.

When t[key] is assigned, "key" is not considered to be a new index, and
the value of t[origkey] is replaced.

When t[0] is assigned, the hash part of the table is reorganized.
t[origkey] is still "Lua is great!", but is no longer found when asking
for t[key].