diff options
author | Justin M. Keyes <justinkz@gmail.com> | 2014-06-12 01:41:12 -0400 |
---|---|---|
committer | Justin M. Keyes <justinkz@gmail.com> | 2014-06-12 01:41:12 -0400 |
commit | bbd75cee82b64796c040b67b3f251a066049e3da (patch) | |
tree | bc0cafef559cbce8147da7a16ed4f0f212b6a62a | |
parent | f39fd5b4c424cc477a168fbf4eebfe315d23e614 (diff) | |
parent | 70f28d938c4ebd01c86f7eefbc5ea991014496e8 (diff) | |
download | rneovim-bbd75cee82b64796c040b67b3f251a066049e3da.tar.gz rneovim-bbd75cee82b64796c040b67b3f251a066049e3da.tar.bz2 rneovim-bbd75cee82b64796c040b67b3f251a066049e3da.zip |
Merge #804 'Coverity fix resource leaks 1b'
-rw-r--r-- | src/nvim/memline.c | 3 | ||||
-rw-r--r-- | src/nvim/ops.c | 105 | ||||
-rw-r--r-- | src/nvim/option.c | 23 | ||||
-rw-r--r-- | src/nvim/search.c | 4 | ||||
-rw-r--r-- | src/nvim/syntax.c | 58 |
5 files changed, 109 insertions, 84 deletions
diff --git a/src/nvim/memline.c b/src/nvim/memline.c index 19c3cfe994..63a05e7b59 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -304,8 +304,7 @@ int ml_open(buf_T *buf) b0p->b0_magic_int = (int)B0_MAGIC_INT; b0p->b0_magic_short = (short)B0_MAGIC_SHORT; b0p->b0_magic_char = B0_MAGIC_CHAR; - STRNCPY(b0p->b0_version, "VIM ", 4); - STRNCPY(b0p->b0_version + 4, Version, 6); + xstrlcpy(xstpcpy((char *) b0p->b0_version, "VIM "), Version, 6); long_to_char((long)mfp->mf_page_size, b0p->b0_page_size); if (!buf->b_spell) { diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 1ee1ce6ecc..67eb6df1bc 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -90,10 +90,10 @@ struct block_def { colnr_T start_char_vcols; /* number of vcols of pre-block char */ }; - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "ops.c.generated.h" #endif + /* * The names of operators. * IMPORTANT: Index must correspond with defines in vim.h!!! @@ -4704,29 +4704,48 @@ get_reg_contents ( return retval; } -/* - * Store string "str" in register "name". - * "maxlen" is the maximum number of bytes to use, -1 for all bytes. - * If "must_append" is TRUE, always append to the register. Otherwise append - * if "name" is an uppercase letter. - * Note: "maxlen" and "must_append" don't work for the "/" register. - * Careful: 'str' is modified, you may have to use a copy! - * If "str" ends in '\n' or '\r', use linewise, otherwise use characterwise. - */ -void write_reg_contents(int name, char_u *str, int maxlen, int must_append) +/// write_reg_contents - store `str` in register `name` +/// +/// @see write_reg_contents_ex +void write_reg_contents(int name, + const char_u *str, + ssize_t len, + int must_append) { - write_reg_contents_ex(name, str, maxlen, must_append, MAUTO, 0L); + write_reg_contents_ex(name, str, len, must_append, MAUTO, 0L); } -void write_reg_contents_ex(int name, char_u *str, int maxlen, int must_append, int yank_type, long block_len) +/// write_reg_contents_ex - store `str` in register `name` +/// +/// If `str` ends in '\n' or '\r', use linewise, otherwise use +/// characterwise. +/// +/// @warning when `name` is '/', `len` and `must_append` are ignored. This +/// means that `str` MUST be NUL-terminated. +/// +/// @param name The name of the register +/// @param str The contents to write +/// @param len If >= 0, write `len` bytes of `str`. Otherwise, write +/// `strlen(str)` bytes. If `len` is larger than the +/// allocated size of `src`, the behaviour is undefined. +/// @param must_append If true, append the contents of `str` to the current +/// contents of the register. Note that regardless of +/// `must_append`, this function will append when `name` +/// is an uppercase letter. +/// @param yank_type MCHAR, MLINE, MBLOCK or MAUTO +/// @param block_len width of visual block +void write_reg_contents_ex(int name, + const char_u *str, + ssize_t len, + int must_append, + int yank_type, + long block_len) { struct yankreg *old_y_previous, *old_y_current; - long len; - if (maxlen >= 0) - len = maxlen; - else - len = (long)STRLEN(str); + if (len < 0) { + len = (ssize_t) STRLEN(str); + } /* Special case: '/' search pattern */ if (name == '/') { @@ -4735,17 +4754,25 @@ void write_reg_contents_ex(int name, char_u *str, int maxlen, int must_append, i } if (name == '=') { - char_u *p, *s; - - p = vim_strnsave(str, (int)len); + size_t offset = 0; + size_t totlen = (size_t) len; - if (must_append) { - s = concat_str(get_expr_line_src(), p); - free(p); - p = s; + if (must_append && expr_line) { + // append has been specified and expr_line already exists, so we'll + // append the new string to expr_line. + size_t exprlen = STRLEN(expr_line); + totlen += exprlen; + offset = exprlen; } - set_expr_line(p); + + // modify the global expr_line, extend/shrink it if necessary (realloc). + // Copy the input string into the adjusted memory at the specified + // offset. + expr_line = xrealloc(expr_line, totlen + 1); + memcpy(expr_line + offset, str, (size_t) len); + expr_line[totlen] = NUL; + return; } @@ -4773,18 +4800,20 @@ void write_reg_contents_ex(int name, char_u *str, int maxlen, int must_append, i y_current = old_y_current; } -/* - * Put a string into a register. When the register is not empty, the string - * is appended. - */ -static void -str_to_reg ( - struct yankreg *y_ptr, /* pointer to yank register */ - int yank_type, /* MCHAR, MLINE, MBLOCK, MAUTO */ - char_u *str, /* string to put in register */ - long len, /* length of string */ - long blocklen /* width of Visual block */ -) +/// str_to_reg - Put a string into a register. +/// +/// When the register is not empty, the string is appended. +/// +/// @param y_ptr pointer to yank register +/// @param yank_type MCHAR, MLINE, MBLOCK or MAUTO +/// @param str string to put in register +/// @param len length of the string +/// @param blocklen width of visual block +static void str_to_reg(struct yankreg *y_ptr, + int yank_type, + const char_u *str, + long len, + long blocklen) { int type; /* MCHAR, MLINE or MBLOCK */ int lnum; diff --git a/src/nvim/option.c b/src/nvim/option.c index 37a5a61d43..6b820ea1ba 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -2216,21 +2216,20 @@ set_options_default ( win_comp_scroll(wp); } -/* - * Set the Vi-default value of a string option. - * Used for 'sh', 'backupskip' and 'term'. - */ -void set_string_default(char *name, char_u *val) +/// Set the Vi-default value of a string option. +/// Used for 'sh', 'backupskip' and 'term'. +/// +/// @param name The name of the option +/// @param val The value of the option +void set_string_default(const char *name, const char_u *val) { - char_u *p; - int opt_idx; - - p = vim_strsave(val); - opt_idx = findoption((char_u *)name); + int opt_idx = findoption((char_u *)name); if (opt_idx >= 0) { - if (options[opt_idx].flags & P_DEF_ALLOCED) + if (options[opt_idx].flags & P_DEF_ALLOCED) { free(options[opt_idx].def_val[VI_DEFAULT]); - options[opt_idx].def_val[VI_DEFAULT] = p; + } + + options[opt_idx].def_val[VI_DEFAULT] = (char_u *) xstrdup((char *) val); options[opt_idx].flags |= P_DEF_ALLOCED; } } diff --git a/src/nvim/search.c b/src/nvim/search.c index 5ba30eeb00..08fdfa4b63 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -375,14 +375,14 @@ void reset_search_dir(void) * Set the last search pattern. For ":let @/ =" and viminfo. * Also set the saved search pattern, so that this works in an autocommand. */ -void set_last_search_pat(char_u *s, int idx, int magic, int setlast) +void set_last_search_pat(const char_u *s, int idx, int magic, int setlast) { free(spats[idx].pat); /* An empty string means that nothing should be matched. */ if (*s == NUL) spats[idx].pat = NULL; else - spats[idx].pat = vim_strsave(s); + spats[idx].pat = (char_u *) xstrdup((char *) s); spats[idx].magic = magic; spats[idx].no_scs = FALSE; spats[idx].off.dir = '/'; diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index baf8e1c8d3..ad8d4fb03d 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -3806,30 +3806,25 @@ static void clear_keywtab(hashtab_T *ht) hash_init(ht); } -/* - * Add a keyword to the list of keywords. - */ -static void -add_keyword ( - char_u *name, /* name of keyword */ - int id, /* group ID for this keyword */ - int flags, /* flags for this keyword */ - short *cont_in_list, /* containedin for this keyword */ - short *next_list, /* nextgroup for this keyword */ - int conceal_char -) +/// Add a keyword to the list of keywords. +/// +/// @param name name of keyword +/// @param id group ID for this keyword +/// @param flags flags for this keyword +/// @param cont_in_list containedin for this keyword +/// @param next_list nextgroup for this keyword +static void add_keyword(char_u *name, + int id, + int flags, + short *cont_in_list, + short *next_list, + int conceal_char) { - hashtab_T *ht; - hashitem_T *hi; - char_u *name_ic; - long_u hash; char_u name_folded[MAXKEYWLEN + 1]; + char_u *name_ic = (curwin->w_s->b_syn_ic) + ? str_foldcase(name, (int)STRLEN(name), name_folded, sizeof(name_folded)) + : name; - if (curwin->w_s->b_syn_ic) - name_ic = str_foldcase(name, (int)STRLEN(name), - name_folded, MAXKEYWLEN + 1); - else - name_ic = name; keyentry_T *kp = xmalloc(sizeof(keyentry_T) + STRLEN(name_ic)); STRCPY(kp->keyword, name_ic); kp->k_syn.id = id; @@ -3837,23 +3832,26 @@ add_keyword ( kp->flags = flags; kp->k_char = conceal_char; kp->k_syn.cont_in_list = copy_id_list(cont_in_list); - if (cont_in_list != NULL) + if (cont_in_list != NULL) { curwin->w_s->b_syn_containedin = TRUE; + } kp->next_list = copy_id_list(next_list); - if (curwin->w_s->b_syn_ic) - ht = &curwin->w_s->b_keywtab_ic; - else - ht = &curwin->w_s->b_keywtab; + long_u hash = hash_hash(kp->keyword); + hashtab_T *ht = (curwin->w_s->b_syn_ic) ? &curwin->w_s->b_keywtab_ic + : &curwin->w_s->b_keywtab; + hashitem_T *hi = hash_lookup(ht, kp->keyword, hash); - hash = hash_hash(kp->keyword); - hi = hash_lookup(ht, kp->keyword, hash); + // even though it looks like only the kp->keyword member is + // being used here, vim uses some pointer trickery to get the orignal + // struct again later by using knowledge of the offset of the keyword + // field in the struct. See the definition of the HI2KE macro. if (HASHITEM_EMPTY(hi)) { - /* new keyword, add to hashtable */ + // new keyword, add to hashtable kp->ke_next = NULL; hash_add_item(ht, hi, kp->keyword, hash); } else { - /* keyword already exists, prepend to list */ + // keyword already exists, prepend to list kp->ke_next = HI2KE(hi); hi->hi_key = KE2HIKEY(kp); } |