diff --git a/src/box/tuple.c b/src/box/tuple.c index 4bbddac1c9fc5b3ae628328680b85b95dced4769..0e315fe5c9bfc2f19a74609a5e58355fefa7b6e6 100644 --- a/src/box/tuple.c +++ b/src/box/tuple.c @@ -162,6 +162,15 @@ tuple_validate_raw(struct tuple_format *format, const char *tuple) size_t region_svp = region_used(region); struct field_map_builder builder; int rc = tuple_field_map_create(format, tuple, true, &builder); + if (rc != 0) + goto end; + + uint32_t field_map_size = field_map_build_size(&builder); + size_t data_offset = sizeof(struct tuple) + field_map_size; + rc = tuple_check_data_offset(data_offset); + if (rc != 0) + goto end; +end: region_truncate(region, region_svp); return rc; } diff --git a/test/box-luatest/tuple_validate_raw_regression_test.lua b/test/box-luatest/tuple_validate_raw_regression_test.lua new file mode 100644 index 0000000000000000000000000000000000000000..04206ca07399cee51d6ad49b8875192b7af50125 --- /dev/null +++ b/test/box-luatest/tuple_validate_raw_regression_test.lua @@ -0,0 +1,39 @@ +local server = require('luatest.server') +local t = require('luatest') + +local g = t.group() + +g.before_each(function(cg) + cg.server = server:new{box_cfg = {}} + cg.server:start() +end) + +g.after_each(function(cg) + cg.server:stop() +end) + + +g.test_key_def_tuple_hash = function(cg) + cg.server:exec(function() + box.schema.space.create("test") + box.space.test:create_index("primary", { + unique = true, parts = { { field = 1, type = "str" } } + }) + + local tup = { "pk1", {}, "value" } + for i = 1, 9000 do + table.insert(tup[2], { i }) + end + box.space.test:insert(tup) + + local bad_operation = function() + box.space.test:create_index("broken", { + parts = { { path = "[*][1]", type = "unsigned", field = 2 } } + }) + end + + t.assert_error_msg_matches( + "Can't create tuple: metadata size .+ is too big", + bad_operation) + end) +end