diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 31e95ef147..d50a5e4bd5 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -2029,7 +2029,9 @@ dictitem_T *tv_dict_item_alloc_len(const char *const key, const size_t key_len) FUNC_ATTR_NONNULL_RET FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC { - dictitem_T *const di = xmalloc(offsetof(dictitem_T, di_key) + key_len + 1); + // Allocating a struct smaller than its static size is UB (#37160) + dictitem_T *const di = xmalloc(MAX(sizeof(dictitem_T), + offsetof(dictitem_T, di_key) + key_len + 1)); memcpy(di->di_key, key, key_len); di->di_key[key_len] = NUL; di->di_flags = DI_FLAGS_ALLOC; diff --git a/test/unit/eval/testutil.lua b/test/unit/eval/testutil.lua index 78788e5837..68669aa145 100644 --- a/test/unit/eval/testutil.lua +++ b/test/unit/eval/testutil.lua @@ -413,7 +413,7 @@ local function alloc_len(len, get_ptr) if type(len) == 'string' or type(len) == 'table' then return #len elseif len == nil then - return eval.strlen(get_ptr()) + return tonumber(eval.strlen(get_ptr())) else return len end @@ -435,7 +435,7 @@ local alloc_logging_t = { end) return { func = 'malloc', - args = { ffi.offsetof('dictitem_T', 'di_key') + size + 1 }, + args = { math.max(ffi.sizeof('dictitem_T'), ffi.offsetof('dictitem_T', 'di_key') + size + 1) }, ret = void(di), } end,