From 8d982ab52269e8adccbc21cc0d6f8ab3b817bf6e Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 9 Apr 2017 20:55:48 +0300 Subject: coverity/13686: Do not allow NUL byte in precondition regex Before this commit it emitted e_spell_trunc in the first case and treated file as completely valid on the second. While first is fine (both errors are actually valid, though old error is probably better), second results in incorrect regex used. --- src/nvim/spellfile.c | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c index bbef1f5032..2c0db0694a 100644 --- a/src/nvim/spellfile.c +++ b/src/nvim/spellfile.c @@ -267,7 +267,7 @@ #define SAL_REM_ACCENTS 4 #define VIMSPELLMAGIC "VIMspell" // string at start of Vim spell file -#define VIMSPELLMAGICL 8 +#define VIMSPELLMAGICL (sizeof(VIMSPELLMAGIC) - 1) #define VIMSPELLVERSION 50 // Section IDs. Only renumber them when VIMSPELLVERSION changes! @@ -516,7 +516,6 @@ spell_load_file ( FILE *fd; char_u buf[VIMSPELLMAGICL]; char_u *p; - int i; int n; int len; char_u *save_sourcing_name = sourcing_name; @@ -558,8 +557,9 @@ spell_load_file ( sourcing_lnum = 0; //
: - for (i = 0; i < VIMSPELLMAGICL; ++i) + for (size_t i = 0; i < VIMSPELLMAGICL; i++) { buf[i] = getc(fd); // + } if (STRNCMP(buf, VIMSPELLMAGIC, VIMSPELLMAGICL) != 0) { EMSG(_("E757: This does not look like a spell file")); goto endFAIL; @@ -983,35 +983,36 @@ static int read_charflags_section(FILE *fd) // Return SP_*ERROR flags. static int read_prefcond_section(FILE *fd, slang_T *lp) { - int cnt; - int i; - int n; - char_u *p; - char_u buf[MAXWLEN + 1]; - // ... - cnt = get2c(fd); // - if (cnt <= 0) + const int cnt = get2c(fd); // + if (cnt <= 0) { return SP_FORMERROR; + } lp->sl_prefprog = xcalloc(cnt, sizeof(regprog_T *)); lp->sl_prefixcnt = cnt; - for (i = 0; i < cnt; ++i) { + for (int i = 0; i < cnt; ++i) { // : - n = getc(fd); // - if (n < 0 || n >= MAXWLEN) + const int n = getc(fd); // + if (n < 0 || n >= MAXWLEN) { return SP_FORMERROR; + } // When is zero we have an empty condition. Otherwise // compile the regexp program used to check for the condition. if (n > 0) { - buf[0] = '^'; // always match at one position only - p = buf + 1; - while (n-- > 0) - *p++ = getc(fd); // - *p = NUL; - lp->sl_prefprog[i] = vim_regcomp(buf, RE_MAGIC + RE_STRING); + char buf[MAXWLEN + 1]; + buf[0] = '^'; // always match at one position only + const size_t read_byte = fread(buf + 1, 1, (size_t)n, fd); + if (read_byte != (size_t)n) { + return feof(fd) ? SP_FORMERROR : SP_OTHERERROR; + } + if (memchr(buf + 1, NUL, (size_t)n)) { + return SP_FORMERROR; + } + buf[n + 1] = NUL; + lp->sl_prefprog[i] = vim_regcomp((char_u *)buf, RE_MAGIC | RE_STRING); } } return 0; -- cgit