changeset 31877:9f28cca2410a v9.0.1271

patch 9.0.1271: using sizeof() and subtract array size is tricky Commit: https://github.com/vim/vim/commit/1b438a8228a415720efb5ca1c0503f5467292e8e Author: zeertzjq <zeertzjq@outlook.com> 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)
author Bram Moolenaar <Bram@vim.org>
date Wed, 01 Feb 2023 14:15:04 +0100
parents b27dae7424a9
children 13d1ba119f07
files src/evalvars.c src/findfile.c src/memline.c src/message.c src/regexp_nfa.c src/spell.c src/spellfile.c src/spellsuggest.c src/version.c src/vim9script.c
diffstat 10 files changed, 15 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- 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);
--- 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;
 
--- 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;
 }
--- 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;
--- 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;
--- 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);
--- 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)
--- 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;
--- 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,
--- 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;