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.
diff --git a/src/textprop.c b/src/textprop.c
index 9198665..2924192 100644
--- a/src/textprop.c
+++ b/src/textprop.c
@@ -287,7 +287,7 @@
props + i * sizeof(textprop_T),
sizeof(textprop_T) * (proplen - i));
- if (buf->b_ml.ml_flags & ML_LINE_DIRTY)
+ if (buf->b_ml.ml_flags & (ML_LINE_DIRTY | ML_ALLOCATED))
vim_free(buf->b_ml.ml_line_ptr);
buf->b_ml.ml_line_ptr = newtext;
buf->b_ml.ml_line_len += sizeof(textprop_T);
@@ -564,7 +564,7 @@
mch_memmove(newtext, text, textlen);
if (len > 0)
mch_memmove(newtext + textlen, props, len);
- if (curbuf->b_ml.ml_flags & ML_LINE_DIRTY)
+ if (curbuf->b_ml.ml_flags & (ML_LINE_DIRTY | ML_ALLOCATED))
vim_free(curbuf->b_ml.ml_line_ptr);
curbuf->b_ml.ml_line_ptr = newtext;
curbuf->b_ml.ml_line_len = textlen + len;
@@ -698,6 +698,8 @@
// need to allocate the line now
if (newtext == NULL)
return;
+ if (buf->b_ml.ml_flags & ML_ALLOCATED)
+ vim_free(buf->b_ml.ml_line_ptr);
buf->b_ml.ml_line_ptr = newtext;
buf->b_ml.ml_flags |= ML_LINE_DIRTY;
}
@@ -1273,6 +1275,8 @@
return;
mch_memmove(newptr, buf->b_ml.ml_line_ptr,
buf->b_ml.ml_line_len);
+ if (buf->b_ml.ml_flags & ML_ALLOCATED)
+ vim_free(buf->b_ml.ml_line_ptr);
buf->b_ml.ml_line_ptr = newptr;
buf->b_ml.ml_flags |= ML_LINE_DIRTY;
@@ -1766,8 +1770,13 @@
colnr_T newlen = (int)textlen + wi * (colnr_T)sizeof(textprop_T);
if ((curbuf->b_ml.ml_flags & ML_LINE_DIRTY) == 0)
- curbuf->b_ml.ml_line_ptr =
- vim_memsave(curbuf->b_ml.ml_line_ptr, newlen);
+ {
+ char_u *p = vim_memsave(curbuf->b_ml.ml_line_ptr, newlen);
+
+ if (curbuf->b_ml.ml_flags & ML_ALLOCATED)
+ vim_free(curbuf->b_ml.ml_line_ptr);
+ curbuf->b_ml.ml_line_ptr = p;
+ }
curbuf->b_ml.ml_flags |= ML_LINE_DIRTY;
curbuf->b_ml.ml_line_len = newlen;
}