0
0
mirror of https://github.com/vim/vim.git synced 2025-09-30 04:44:14 -04:00

patch 9.0.0013: reproducing memory access errors can be difficult

Problem:    Reproducing memory access errors can be difficult.
Solution:   When testing, copy each line to allocated memory, so that valgrind
            can detect accessing memory before and/or after it.  Fix uncovered
            problems.
This commit is contained in:
Bram Moolenaar
2022-06-30 22:13:59 +01:00
parent cdbfc6dbab
commit fa4873ccfc
15 changed files with 119 additions and 33 deletions

View File

@@ -858,7 +858,8 @@ ml_close(buf_T *buf, int del_file)
if (buf->b_ml.ml_mfp == NULL) // not open
return;
mf_close(buf->b_ml.ml_mfp, del_file); // close the .swp file
if (buf->b_ml.ml_line_lnum != 0 && (buf->b_ml.ml_flags & ML_LINE_DIRTY))
if (buf->b_ml.ml_line_lnum != 0
&& (buf->b_ml.ml_flags & (ML_LINE_DIRTY | ML_ALLOCATED)))
vim_free(buf->b_ml.ml_line_ptr);
vim_free(buf->b_ml.ml_stack);
#ifdef FEAT_BYTEOFF
@@ -2620,7 +2621,6 @@ ml_get_buf(
--recursive;
}
ml_flush_line(buf);
buf->b_ml.ml_flags &= ~ML_LINE_DIRTY;
errorret:
STRCPY(questions, "???");
buf->b_ml.ml_line_len = 4;
@@ -2686,17 +2686,44 @@ errorret:
buf->b_ml.ml_line_ptr = (char_u *)dp + start;
buf->b_ml.ml_line_len = len;
buf->b_ml.ml_line_lnum = lnum;
buf->b_ml.ml_flags &= ~ML_LINE_DIRTY;
buf->b_ml.ml_flags &= ~(ML_LINE_DIRTY | ML_ALLOCATED);
}
if (will_change)
{
buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS);
#ifdef FEAT_EVAL
if (ml_get_alloc_lines && (buf->b_ml.ml_flags & ML_ALLOCATED))
// can't make the change in the data block
buf->b_ml.ml_flags |= ML_LINE_DIRTY;
#endif
}
#ifdef FEAT_EVAL
if (ml_get_alloc_lines
&& (buf->b_ml.ml_flags & (ML_LINE_DIRTY | ML_ALLOCATED)) == 0)
{
char_u *p = alloc(buf->b_ml.ml_line_len);
// make sure the text is in allocated memory
if (p != NULL)
{
memmove(p, buf->b_ml.ml_line_ptr, buf->b_ml.ml_line_len);
buf->b_ml.ml_line_ptr = p;
buf->b_ml.ml_flags |= ML_ALLOCATED;
if (will_change)
// can't make the change in the data block
buf->b_ml.ml_flags |= ML_LINE_DIRTY;
}
}
#endif
return buf->b_ml.ml_line_ptr;
}
/*
* Check if a line that was just obtained by a call to ml_get
* is in allocated memory.
* This ignores ML_ALLOCATED to get the same behavior as without the test
* override.
*/
int
ml_line_alloced(void)
@@ -3409,6 +3436,8 @@ ml_replace(linenr_T lnum, char_u *line, int copy)
* "len_arg" is the length of the text, excluding NUL.
* If "has_props" is TRUE then "line_arg" includes the text properties and
* "len_arg" includes the NUL of the text.
* When "copy" is TRUE copy the text into allocated memory, otherwise
* "line_arg" must be allocated and will be consumed here.
*/
int
ml_replace_len(
@@ -3454,7 +3483,6 @@ ml_replace_len(
{
// another line is buffered, flush it
ml_flush_line(curbuf);
curbuf->b_ml.ml_flags &= ~ML_LINE_DIRTY;
#ifdef FEAT_PROP_POPUP
if (curbuf->b_has_textprop && !has_props)
@@ -3488,8 +3516,8 @@ ml_replace_len(
}
#endif
if (curbuf->b_ml.ml_flags & ML_LINE_DIRTY) // same line allocated
vim_free(curbuf->b_ml.ml_line_ptr); // free it
if (curbuf->b_ml.ml_flags & (ML_LINE_DIRTY | ML_ALLOCATED))
vim_free(curbuf->b_ml.ml_line_ptr); // free allocated line
curbuf->b_ml.ml_line_ptr = line;
curbuf->b_ml.ml_line_len = len;
@@ -4064,7 +4092,10 @@ ml_flush_line(buf_T *buf)
entered = FALSE;
}
else if (buf->b_ml.ml_flags & ML_ALLOCATED)
vim_free(buf->b_ml.ml_line_ptr);
buf->b_ml.ml_flags &= ~(ML_LINE_DIRTY | ML_ALLOCATED);
buf->b_ml.ml_line_lnum = 0;
}