Skip to content
Snippets Groups Projects
Commit 73dd3a8e authored by Vladimir Davydov's avatar Vladimir Davydov
Browse files

tuple: fix crash on hashing tuple with double fields

`tuple_hash_field()` doesn't advance the MsgPack cursor after hashing
a tuple field with the type `double`, which can result in crashes both
in memtx (while inserting a tuple into a hash index) and in vinyl
(while writing a bloom filter on dump or compaction).

The bug was introduced by commit 51af059c ("box: compare and hash
msgpack value of double key field as double").

Closes #10090

NO_DOC=bug fix

(cherry picked from commit bc0daf99)
parent 9b8fb7ab
No related branches found
No related tags found
No related merge requests found
## bugfix/core
* Fixed a bug when hashing a tuple with `double` fields could crash.
The bug could trigger a crash in memtx while inserting a tuple into
a `hash` index and in vinyl while writing a bloom filter on dump or
compaction (gh-10090).
......@@ -313,7 +313,7 @@ tuple_hash_field(uint32_t *ph1, uint32_t *pcarry, const char **field,
* This will only fail if the mp_type is not numeric, which is
* impossible here (see field_mp_plain_type_is_compatible).
*/
if (mp_read_double_lossy(&f, &value) == -1)
if (mp_read_double_lossy(field, &value) == -1)
unreachable();
char *double_msgpack_end = mp_encode_double(buf, value);
size = double_msgpack_end - buf;
......
local server = require('luatest.server')
local t = require('luatest')
local g = t.group()
g.before_all(function(cg)
cg.server = server:new()
cg.server:start()
end)
g.after_all(function(cg)
cg.server:drop()
end)
g.after_each(function(cg)
cg.server:exec(function()
if box.space.test ~= nil then
box.space.test:drop()
end
end)
end)
g.test_tuple_hash_double = function(cg)
cg.server:exec(function()
local s = box.schema.create_space('test')
s:create_index('pk', {
type = 'hash',
parts = {
{1, 'double'}, {2, 'string'}, {3, 'double'},
},
})
s:insert{1, 'x', 0.5}
s:insert{0.5, 'y', 1}
s:delete{0.5, 'y', 1}
t.assert_equals(s:select({}, {fullscan = true}), {{1, 'x', 0.5}})
end)
end
local server = require('luatest.server')
local t = require('luatest')
local g = t.group()
g.before_all(function(cg)
cg.server = server:new()
cg.server:start()
end)
g.after_all(function(cg)
cg.server:drop()
end)
g.after_each(function(cg)
cg.server:exec(function()
if box.space.test ~= nil then
box.space.test:drop()
end
end)
end)
g.test_tuple_hash_double = function(cg)
cg.server:exec(function()
local s = box.schema.create_space('test', {engine = 'vinyl'})
s:create_index('pk', {
parts = {
{1, 'double'}, {2, 'string'}, {3, 'double'},
},
})
s:insert{1, 'x', 0.5}
s:insert{0.5, 'y', 1}
box.snapshot()
s:delete{0.5, 'y', 1}
box.snapshot()
t.assert_equals(s:select({}, {fullscan = true}), {{1, 'x', 0.5}})
end)
end
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