Skip to content
Snippets Groups Projects
Commit 9dfb4fdf authored by Dmitry Ivanov's avatar Dmitry Ivanov
Browse files

fix: check tuple metadata size in tuple_validate_raw

This check is needed to prevent the following scenario:

```
box.cfg()

box.schema.space.create("test")
box.space.test:create_index("primary", {
        unique = true, parts = { { field = 1, type = "str" } }
})

local t = { "pk1", {}, "value" }
for i = 1, 9000 do
  table.insert(t[2], { i })
end
box.space.test:insert(t)

-- This succeeds, but shouldn't!
box.space.test:create_index("broken", {
        parts = { { path = "[*][1]", type = "unsigned", field = 2 } }
})
-- This fails with an error due to metadata update...
box.space.test:update("pk1", { { "=", 3, "new value" } })
```

```
2025-03-03 10:26:13.519 [41046] main tuple.h:473 E> ER_TUPLE_METADATA_IS_TOO_BIG: Can't create tuple: metadata size 36022 is too big
```

NO_DOC=picodata
NO_CHANGELOG=picodata
parent b06e25ff
No related tags found
1 merge request!230fix: check tuple metadata size in tuple_validate_raw
Pipeline #63887 passed
......@@ -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;
}
......
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
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