diff options
author | dundargoc <33953936+dundargoc@users.noreply.github.com> | 2023-02-02 23:56:25 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-02-02 23:56:25 +0100 |
commit | ebd2372f928c6f1cfe823d36aabf479f6930232f (patch) | |
tree | 277d19740498c2be4486df9bd8dd411b5b4547d1 | |
parent | 0ea4156464c982f0451cd486e2152934c3dd2204 (diff) | |
download | rneovim-ebd2372f928c6f1cfe823d36aabf479f6930232f.tar.gz rneovim-ebd2372f928c6f1cfe823d36aabf479f6930232f.tar.bz2 rneovim-ebd2372f928c6f1cfe823d36aabf479f6930232f.zip |
refactor: use flexible arrays instead of the length-of-one trick (#22072)
The "length-of-one" trick, where the last element of a struct is an
array of size 1, but extra size is allocated when calling malloc where
it uses more than 1 element in the array, cause problems with some
compilers. Some compilers set _FORTIFY_SOURCE=2 by default which
incorrectly considers it as an overflow. More information:
https://github.com/neovim/neovim/issues/223#issuecomment-1413828554
Using flexible array members allows us to to properly convey to the
compiler that its size may be larger than 1. This also enables us to
remove lengthy workarounds that are unreliable, as they depend on
CMAKE_BUILD_TYPE which isn't defined for multi-config generators.
Closes: https://github.com/neovim/neovim/issues/223
-rw-r--r-- | CMakeLists.txt | 14 | ||||
-rwxr-xr-x | src/nvim/CMakeLists.txt | 28 | ||||
-rw-r--r-- | src/nvim/file_search.c | 2 | ||||
-rw-r--r-- | src/nvim/memline.c | 4 | ||||
-rw-r--r-- | src/nvim/message.c | 2 | ||||
-rw-r--r-- | src/nvim/regexp_defs.h | 4 | ||||
-rw-r--r-- | src/nvim/sign_defs.h | 2 | ||||
-rw-r--r-- | src/nvim/spell_defs.h | 2 | ||||
-rw-r--r-- | src/nvim/spellfile.c | 2 | ||||
-rw-r--r-- | src/nvim/spellsuggest.c | 2 | ||||
-rw-r--r-- | src/nvim/syntax_defs.h | 2 |
11 files changed, 11 insertions, 53 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c0d999ab8..2c9d7f339f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -175,20 +175,6 @@ if(CMAKE_C_FLAGS_RELWITHDEBINFO MATCHES DNDEBUG) string(REPLACE "-DNDEBUG" "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}") endif() -# gcc 4.0+ sets _FORTIFY_SOURCE=2 automatically. This currently -# does not work with Neovim due to some uses of dynamically-sized structures. -# https://github.com/neovim/neovim/issues/223 - -# Include the build type's default flags in the check for _FORTIFY_SOURCE, -# otherwise we may incorrectly identify the level as acceptable and find out -# later that it was not when optimizations were enabled. CFLAGS is applied -# even though you don't see it in CMAKE_REQUIRED_FLAGS. -set(INIT_FLAGS_NAME CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE}) -string(TOUPPER ${INIT_FLAGS_NAME} INIT_FLAGS_NAME) -if(${INIT_FLAGS_NAME}) - set(CMAKE_REQUIRED_FLAGS "${${INIT_FLAGS_NAME}}") -endif() - option(LOG_LIST_ACTIONS "Add list actions logging" OFF) option(CLANG_ASAN_UBSAN "Enable Clang address & undefined behavior sanitizer for nvim binary." OFF) diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 7b56af59da..62b661dc2d 100755 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -219,34 +219,6 @@ endif() list(REMOVE_ITEM CMAKE_REQUIRED_INCLUDES "${TreeSitter_INCLUDE_DIRS}") list(REMOVE_ITEM CMAKE_REQUIRED_LIBRARIES "${TreeSitter_LIBRARIES}") -# Include <string.h> because some toolchains define _FORTIFY_SOURCE=2 in -# internal header files, which should in turn be #included by <string.h>. -check_c_source_compiles(" -#include <string.h> - -#if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 1 -#error \"_FORTIFY_SOURCE > 1\" -#endif -int -main(void) -{ - return 0; -} -" HAS_ACCEPTABLE_FORTIFY) - -if(NOT HAS_ACCEPTABLE_FORTIFY) - message(STATUS "Unsupported _FORTIFY_SOURCE found, forcing _FORTIFY_SOURCE=1") - # Extract possible prefix to _FORTIFY_SOURCE (e.g. -Wp,-D_FORTIFY_SOURCE). - string(REGEX MATCH "[^\ ]+-D_FORTIFY_SOURCE" _FORTIFY_SOURCE_PREFIX "${CMAKE_C_FLAGS}") - string(REPLACE "-D_FORTIFY_SOURCE" "" _FORTIFY_SOURCE_PREFIX "${_FORTIFY_SOURCE_PREFIX}" ) - if(NOT _FORTIFY_SOURCE_PREFIX STREQUAL "") - message(STATUS "Detected _FORTIFY_SOURCE Prefix=${_FORTIFY_SOURCE_PREFIX}") - endif() - # -U in add_definitions doesn't end up in the correct spot, so we add it to - # the flags variable instead. - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_FORTIFY_SOURCE_PREFIX}-U_FORTIFY_SOURCE ${_FORTIFY_SOURCE_PREFIX}-D_FORTIFY_SOURCE=1") -endif() - target_compile_definitions(main_lib INTERFACE INCLUDE_GENERATED_DECLARATIONS) # Remove --sort-common from linker flags, as this seems to cause bugs (see #2641, #3374). diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c index a0435afd65..42ba0bee97 100644 --- a/src/nvim/file_search.c +++ b/src/nvim/file_search.c @@ -117,7 +117,7 @@ typedef struct ff_visited { FileID file_id; // The memory for this struct is allocated according to the length of // ffv_fname. - char ffv_fname[1]; // actually longer + char ffv_fname[]; } ff_visited_T; // We might have to manage several visited lists during a search. diff --git a/src/nvim/memline.c b/src/nvim/memline.c index b3fc64a68c..dfca19aa96 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -117,7 +117,7 @@ struct pointer_block { uint16_t pb_id; // ID for pointer block: PTR_ID uint16_t pb_count; // number of pointers in this block uint16_t pb_count_max; // maximum value for pb_count - PTR_EN pb_pointer[1]; // list of pointers to blocks (actually longer) + PTR_EN pb_pointer[]; // list of pointers to blocks // followed by empty space until end of page }; @@ -133,7 +133,7 @@ struct data_block { unsigned db_txt_end; // byte just after data block // linenr_T db_line_count; long db_line_count; // number of lines in this block - unsigned db_index[1]; // index for start of line (actually bigger) + unsigned db_index[]; // index for start of line // followed by empty space up to db_txt_start // followed by the text in the lines until // end of page diff --git a/src/nvim/message.c b/src/nvim/message.c index 3b3dfcd5b6..40453211b4 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -64,7 +64,7 @@ struct msgchunk_S { char sb_eol; // true when line ends after this text int sb_msg_col; // column in which text starts int sb_attr; // text attributes - char sb_text[1]; // text to be displayed, actually longer + char sb_text[]; // text to be displayed }; // Magic chars used in confirm dialog strings diff --git a/src/nvim/regexp_defs.h b/src/nvim/regexp_defs.h index 16bb2db464..b27a5b5942 100644 --- a/src/nvim/regexp_defs.h +++ b/src/nvim/regexp_defs.h @@ -102,7 +102,7 @@ typedef struct { char_u *regmust; int regmlen; char_u reghasz; - char_u program[1]; // actually longer.. + char_u program[]; } bt_regprog_T; // Structure representing a NFA state. @@ -138,7 +138,7 @@ typedef struct { char *pattern; int nsubexp; // number of () int nstate; - nfa_state_T state[1]; // actually longer.. + nfa_state_T state[]; } nfa_regprog_T; // Structure to be used for single-line matching. diff --git a/src/nvim/sign_defs.h b/src/nvim/sign_defs.h index 7aa06ce48a..bae5344588 100644 --- a/src/nvim/sign_defs.h +++ b/src/nvim/sign_defs.h @@ -12,7 +12,7 @@ typedef struct signgroup_S { int sg_next_sign_id; ///< next sign id for this group uint16_t sg_refcount; ///< number of signs in this group - char sg_name[1]; ///< sign group name, actually longer + char sg_name[]; ///< sign group name } signgroup_T; // Macros to get the sign group structure from the group name diff --git a/src/nvim/spell_defs.h b/src/nvim/spell_defs.h index 726af7d698..4d365deab1 100644 --- a/src/nvim/spell_defs.h +++ b/src/nvim/spell_defs.h @@ -243,7 +243,7 @@ typedef enum { typedef struct wordcount_S { uint16_t wc_count; ///< nr of times word was seen - char_u wc_word[1]; ///< word, actually longer + char_u wc_word[]; ///< word } wordcount_T; #define WC_KEY_OFF offsetof(wordcount_T, wc_word) diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c index 7b124ae6b6..5e7ebc4c87 100644 --- a/src/nvim/spellfile.c +++ b/src/nvim/spellfile.c @@ -404,7 +404,7 @@ typedef struct sblock_S sblock_T; struct sblock_S { int sb_used; // nr of bytes already in use sblock_T *sb_next; // next block in list - char_u sb_data[1]; // data, actually longer + char_u sb_data[]; // data }; // A node in the tree. diff --git a/src/nvim/spellsuggest.c b/src/nvim/spellsuggest.c index 54b6f552b5..0ddf07e3a6 100644 --- a/src/nvim/spellsuggest.c +++ b/src/nvim/spellsuggest.c @@ -2708,7 +2708,7 @@ static int stp_sal_score(suggest_T *stp, suginfo_T *su, slang_T *slang, char_u * /// handled already. typedef struct { int16_t sft_score; ///< lowest score used - char_u sft_word[1]; ///< soundfolded word, actually longer + char_u sft_word[]; ///< soundfolded word } sftword_T; static sftword_T dumsft; diff --git a/src/nvim/syntax_defs.h b/src/nvim/syntax_defs.h index 3f3101f7e3..218cd3623d 100644 --- a/src/nvim/syntax_defs.h +++ b/src/nvim/syntax_defs.h @@ -30,7 +30,7 @@ struct keyentry { int16_t *next_list; // ID list for next match (if non-zero) int flags; int k_char; // conceal substitute character - char keyword[1]; // actually longer + char keyword[]; }; // Struct used to store one state of the state stack. |