Skip to content
Snippets Groups Projects
Commit f4de9faf authored by Magomed Kostoev's avatar Magomed Kostoev Committed by Aleksandr Lyapunov
Browse files

box: fix invalid memory access in tuple_compare_with_key_sequential

Since number type was introduced we can not assume if tuples are
equal by comparison then their sizes are equal too. So the place
the assumption is used is fixed.

Closes #8899

NO_DOC=bugfix
parent 9d28d372
No related branches found
No related tags found
No related merge requests found
## bugfix/box
* Fixed the invalid memory access in a corner case of a specialized comparison
function (gh-8899).
......@@ -941,8 +941,9 @@ tuple_compare_with_key_sequential(struct tuple *tuple, hint_t tuple_hint,
cmp_part_count = part_count;
}
bool unused;
rc = key_compare_parts<is_nullable>(tuple_key, key, cmp_part_count,
key_def, &unused);
rc = key_compare_and_skip_parts<is_nullable>(&tuple_key, &key,
cmp_part_count,
key_def, &unused);
if (!has_optional_parts || rc != 0)
return rc;
/*
......@@ -950,11 +951,6 @@ tuple_compare_with_key_sequential(struct tuple *tuple, hint_t tuple_hint,
* corresponding key fields to be equal to NULL.
*/
if (field_count < part_count) {
/*
* Key's and tuple's first field_count fields are
* equal, and their bsize too.
*/
key += tuple_bsize(tuple) - mp_sizeof_array(field_count);
for (uint32_t i = field_count; i < part_count;
++i, mp_next(&key)) {
if (mp_typeof(*key) != MP_NIL)
......
local server = require('luatest.server')
local t = require('luatest')
local g = t.group('gh-8899-tuple-compare-with-key-slowpath-last-loop')
g.before_all(function()
g.server = server:new()
g.server:start()
end)
g.after_all(function()
g.server:stop()
end)
g.test_tuple_compare_with_key_slowpath_last_loop = function()
g.server:exec(function()
local ffi = require('ffi')
local function double(n)
return ffi.cast('double', n)
end
local s = box.schema.space.create('test', {engine = 'memtx'})
s:create_index('pk')
local sk = s:create_index('sk', {parts = {
{1, 'unsigned'},
{2, 'number', is_nullable = true},
{3, 'number', is_nullable = true}
}})
-- 1-byte unsigned in DB, 8-byte double in request.
s:replace({1, 2})
t.assert_equals(sk:select({1, double(2), box.NULL}, {iterator = 'EQ'}),
{{1, 2}})
-- 8-byte double in DB, 1-byte unsigned in request.
s:replace({1, double(3)})
t.assert_equals(sk:select({1, 3, box.NULL}, {iterator = 'EQ'}),
{{1, 3}})
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