Skip to content
Snippets Groups Projects
Commit 822aedfe authored by Alexander Turenko's avatar Alexander Turenko Committed by Alexander Turenko
Browse files

odict: fix ffi.new('void *') as a key

The problem is found by @ochaton.

NO_DOC=bugfix
NO_CHANGELOG=not a public API
parent 97a801e1
No related branches found
No related tags found
No related merge requests found
......@@ -65,7 +65,7 @@ local function gen(od, prev_key)
-- The previous key is nil only on the first call of the
-- generator function.
local id = prev_key == nil and 0 or ctx.key2id[prev_key]
local id = type(prev_key) == 'nil' and 0 or ctx.key2id[prev_key]
-- NB: This assert doesn't catch all the kinds of changes
-- during an iteration. It rather verifies a precondition
-- for the following cycle.
......@@ -80,7 +80,7 @@ local function gen(od, prev_key)
-- id2key may contain a stalled entry, because __newindex
-- is not called on assignment of an existing field,
-- including assignment to nil.
if key ~= nil and od[key] ~= nil then
if type(key) ~= 'nil' and od[key] ~= nil then
return key, od[key]
end
end
......@@ -148,11 +148,11 @@ local function reindex(od, ctx)
for id = 1, old_max_id do
local key = ctx.id2key[id]
-- Drop the given key-id pair from the key<->id mappings.
if key ~= nil then
if type(key) ~= 'nil' then
release(ctx, key)
end
-- Add the new key-id pair into the key<->id mappings.
if key ~= nil and od[key] ~= nil then
if type(key) ~= 'nil' and od[key] ~= nil then
track(ctx, key)
end
end
......
local fun = require('fun')
local ffi = require('ffi')
local odict = require('internal.config.utils.odict')
local t = require('luatest')
......@@ -117,6 +118,41 @@ g.test_pairs_delete_and_set = function()
})
end
-- Using cdata as a key is unusual, but it is legal in LuaJIT.
--
-- There is a potential pitfall: ffi.new('void *') == nil. Let's
-- verify that we handle such a key correctly.
g.test_null_as_key = function()
local od = odict.new()
local nulls = {
ffi.new('void *'),
ffi.new('void *'),
ffi.new('void *'),
}
od[nulls[1]] = 1
od[nulls[2]] = 2
od[nulls[3]] = 3
local res = {}
for k, v in odict.pairs(od) do
table.insert(res, {k, v})
end
-- It doesn't differentiate nulls.
t.assert_equals(res, {
{nulls[1], 1},
{nulls[2], 2},
{nulls[3], 3},
})
-- It does.
t.assert(rawequal(res[1][1], nulls[1]))
t.assert(rawequal(res[2][1], nulls[2]))
t.assert(rawequal(res[3][1], nulls[3]))
end
-- {{{ Helpers for reindexing test cases
-- Parse a range expressed like Python's slice operator.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment