Mercurial > vim
diff src/userfunc.c @ 31655:01d05b001dda v9.0.1160
patch 9.0.1160: ASAN error for ufunc_T allocated with wrong size
Commit: https://github.com/vim/vim/commit/e01e5215f927f83778ad7494abb0007aa52d08c3
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Jan 8 20:31:18 2023 +0000
patch 9.0.1160: ASAN error for ufunc_T allocated with wrong size
Problem: ASAN error for ufunc_T allocated with wrong size.
Solution: Make sure the size can always fit the struct.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 08 Jan 2023 21:45:03 +0100 |
parents | ec76f9d2319e |
children | 4473453c09b1 |
line wrap: on
line diff
--- a/src/userfunc.c +++ b/src/userfunc.c @@ -641,6 +641,19 @@ get_lambda_name(void) return name; } +/* + * Allocate a "ufunc_T" for a function called "name". + * Makes sure the size is right. + */ + static ufunc_T * +alloc_ufunc(char_u *name) +{ + // When the name is short we need to make sure we allocate enough bytes for + // the whole struct, including any padding. + size_t len = offsetof(ufunc_T, uf_name) + STRLEN(name) + 1; + return alloc_clear(len < sizeof(ufunc_T) ? sizeof(ufunc_T) : len); +} + #if defined(FEAT_LUA) || defined(PROTO) /* * Registers a native C callback which can be called from Vim script. @@ -652,7 +665,7 @@ register_cfunc(cfunc_T cb, cfunc_free_T char_u *name = get_lambda_name(); ufunc_T *fp; - fp = alloc_clear(offsetof(ufunc_T, uf_name) + STRLEN(name) + 1); + fp = alloc_ufunc(name); if (fp == NULL) return NULL; @@ -1356,7 +1369,7 @@ lambda_function_body( } name = get_lambda_name(); - ufunc = alloc_clear(offsetof(ufunc_T, uf_name) + STRLEN(name) + 1); + ufunc = alloc_ufunc(name); if (ufunc == NULL) goto erret; set_ufunc_name(ufunc, name); @@ -1557,7 +1570,7 @@ get_lambda_tv( char_u *line_end; char_u *name = get_lambda_name(); - fp = alloc_clear(offsetof(ufunc_T, uf_name) + STRLEN(name) + 1); + fp = alloc_ufunc(name); if (fp == NULL) goto errret; fp->uf_def_status = UF_NOT_COMPILED; @@ -2558,7 +2571,7 @@ copy_lambda_to_global_func( return FAIL; } - fp = alloc_clear(offsetof(ufunc_T, uf_name) + STRLEN(global) + 1); + fp = alloc_ufunc(global); if (fp == NULL) return FAIL; @@ -5081,7 +5094,7 @@ define_function( } } - fp = alloc_clear(offsetof(ufunc_T, uf_name) + STRLEN(name) + 1); + fp = alloc_ufunc(name); if (fp == NULL) goto erret; fp_allocated = TRUE; @@ -5525,10 +5538,7 @@ get_user_func_name(expand_T *xp, int idx ufunc_T * copy_function(ufunc_T *fp) { - // The struct may have padding, make sure we allocate at least the size of - // the struct. - size_t len = offsetof(ufunc_T, uf_name) + STRLEN(fp->uf_name) + 1; - ufunc_T *ufunc = alloc_clear(len < sizeof(ufunc_T) ? sizeof(ufunc_T) : len); + ufunc_T *ufunc = alloc_ufunc(fp->uf_name); if (ufunc == NULL) return NULL;