[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Numeric key collision related bug in Lua 5.3
- From: Dirk Laurie <dirk.laurie@...>
- Date: Tue, 21 Apr 2015 18:36:33 +0200
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].