# HG changeset patch # User Bram Moolenaar # Date 1675257304 -3600 # Node ID 9f28cca2410aab17f517f4c5c760c3e7efd240e6 # Parent b27dae7424a9d21bb5a54ceb1d33861dd064a17c patch 9.0.1271: using sizeof() and subtract array size is tricky Commit: https://github.com/vim/vim/commit/1b438a8228a415720efb5ca1c0503f5467292e8e Author: zeertzjq Date: Wed Feb 1 13:11:15 2023 +0000 patch 9.0.1271: using sizeof() and subtract array size is tricky Problem: Using sizeof() and subtract array size is tricky. Solution: Use offsetof() instead. (closes https://github.com/vim/vim/issues/11926) diff --git a/src/evalvars.c b/src/evalvars.c --- a/src/evalvars.c +++ b/src/evalvars.c @@ -3960,7 +3960,7 @@ set_var_const( || STRNCMP(name, "g:", 2) == 0 || var_in_autoload)) goto failed; - di = alloc(sizeof(dictitem_T) + STRLEN(varname)); + di = alloc(offsetof(dictitem_T, di_key) + STRLEN(varname) + 1); if (di == NULL) goto failed; STRCPY(di->di_key, varname); diff --git a/src/findfile.c b/src/findfile.c --- a/src/findfile.c +++ b/src/findfile.c @@ -1344,7 +1344,8 @@ ff_check_visited( /* * New file/dir. Add it to the list of visited files/dirs. */ - vp = alloc(sizeof(ff_visited_T) + STRLEN(ff_expand_buffer)); + vp = alloc( + offsetof(ff_visited_T, ffv_fname) + STRLEN(ff_expand_buffer) + 1); if (vp == NULL) return OK; diff --git a/src/memline.c b/src/memline.c --- a/src/memline.c +++ b/src/memline.c @@ -130,7 +130,7 @@ struct data_block #define DB_INDEX_MASK (~DB_MARKED) #define INDEX_SIZE (sizeof(unsigned)) // size of one db_index entry -#define HEADER_SIZE (sizeof(DATA_BL) - INDEX_SIZE) // size of data block header +#define HEADER_SIZE (offsetof(DATA_BL, db_index)) // size of data block header #define B0_FNAME_SIZE_ORG 900 // what it was in older versions #define B0_FNAME_SIZE_NOCRYPT 898 // 2 bytes used for other things @@ -4162,8 +4162,9 @@ ml_new_ptr(memfile_T *mfp) pp = (PTR_BL *)(hp->bh_data); pp->pb_id = PTR_ID; pp->pb_count = 0; - pp->pb_count_max = (short_u)((mfp->mf_page_size - sizeof(PTR_BL)) - / sizeof(PTR_EN) + 1); + pp->pb_count_max = + (short_u)((mfp->mf_page_size - offsetof(PTR_BL, pb_pointer)) + / sizeof(PTR_EN)); return hp; } diff --git a/src/message.c b/src/message.c --- a/src/message.c +++ b/src/message.c @@ -2739,7 +2739,7 @@ store_sb_text( if (s > *sb_str) { - mp = alloc(sizeof(msgchunk_T) + (s - *sb_str)); + mp = alloc(offsetof(msgchunk_T, sb_text) + (s - *sb_str) + 1); if (mp != NULL) { mp->sb_eol = finish; diff --git a/src/regexp_nfa.c b/src/regexp_nfa.c --- a/src/regexp_nfa.c +++ b/src/regexp_nfa.c @@ -7505,7 +7505,7 @@ nfa_regcomp(char_u *expr, int re_flags) post2nfa(postfix, post_ptr, TRUE); // allocate the regprog with space for the compiled regexp - prog_size = sizeof(nfa_regprog_T) + sizeof(nfa_state_T) * (nstate - 1); + prog_size = offsetof(nfa_regprog_T, state) + sizeof(nfa_state_T) * nstate; prog = alloc(prog_size); if (prog == NULL) goto fail; diff --git a/src/spell.c b/src/spell.c --- a/src/spell.c +++ b/src/spell.c @@ -1848,7 +1848,7 @@ count_common_word( hi = hash_lookup(&lp->sl_wordcount, p, hash); if (HASHITEM_EMPTY(hi)) { - wc = alloc(sizeof(wordcount_T) + STRLEN(p)); + wc = alloc(offsetof(wordcount_T, wc_word) + STRLEN(p) + 1); if (wc == NULL) return; STRCPY(wc->wc_word, p); diff --git a/src/spellfile.c b/src/spellfile.c --- a/src/spellfile.c +++ b/src/spellfile.c @@ -4305,7 +4305,7 @@ getroom( bl = NULL; else // Allocate a block of memory. It is not freed until much later. - bl = alloc_clear(sizeof(sblock_T) + SBLOCKSIZE); + bl = alloc_clear(offsetof(sblock_T, sb_data) + SBLOCKSIZE + 1); if (bl == NULL) { if (!spin->si_did_emsg) diff --git a/src/spellsuggest.c b/src/spellsuggest.c --- a/src/spellsuggest.c +++ b/src/spellsuggest.c @@ -3228,7 +3228,7 @@ add_sound_suggest( hi = hash_lookup(&slang->sl_sounddone, goodword, hash); if (HASHITEM_EMPTY(hi)) { - sft = alloc(sizeof(sftword_T) + STRLEN(goodword)); + sft = alloc(offsetof(sftword_T, sft_word) + STRLEN(goodword) + 1); if (sft != NULL) { sft->sft_score = score; diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -696,6 +696,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1271, +/**/ 1270, /**/ 1269, diff --git a/src/vim9script.c b/src/vim9script.c --- a/src/vim9script.c +++ b/src/vim9script.c @@ -922,7 +922,7 @@ update_vim9_script_var( // svar_T and create a new sallvar_T. sv = ((svar_T *)si->sn_var_vals.ga_data) + si->sn_var_vals.ga_len; newsav = (sallvar_T *)alloc_clear( - sizeof(sallvar_T) + STRLEN(name)); + offsetof(sallvar_T, sav_key) + STRLEN(name) + 1); if (newsav == NULL) return;