patch 8.1.2018: using freed memory when out of memory and displaying message
Problem: Using freed memory when out of memory and displaying message.
Solution: Make a copy of the message first.
diff --git a/src/main.c b/src/main.c
index 1eb4911..6fe581c 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1276,16 +1276,19 @@
/* display message after redraw */
if (keep_msg != NULL)
{
- char_u *p;
+ char_u *p = vim_strsave(keep_msg);
- // msg_attr_keep() will set keep_msg to NULL, must free the
- // string here. Don't reset keep_msg, msg_attr_keep() uses it
- // to check for duplicates. Never put this message in history.
- p = keep_msg;
- msg_hist_off = TRUE;
- msg_attr((char *)p, keep_msg_attr);
- msg_hist_off = FALSE;
- vim_free(p);
+ if (p != NULL)
+ {
+ // msg_start() will set keep_msg to NULL, make a copy
+ // first. Don't reset keep_msg, msg_attr_keep() uses it to
+ // check for duplicates. Never put this message in
+ // history.
+ msg_hist_off = TRUE;
+ msg_attr((char *)p, keep_msg_attr);
+ msg_hist_off = FALSE;
+ vim_free(p);
+ }
}
if (need_fileinfo) /* show file info after redraw */
{
diff --git a/src/message.c b/src/message.c
index b5aff84..7810c5b 100644
--- a/src/message.c
+++ b/src/message.c
@@ -168,11 +168,6 @@
ch_log(NULL, "ERROR: %s", (char *)s);
#endif
- /* When displaying keep_msg, don't let msg_start() free it, caller must do
- * that. */
- if ((char_u *)s == keep_msg)
- keep_msg = NULL;
-
/* Truncate the message if needed. */
msg_start();
buf = msg_strtrunc((char_u *)s, FALSE);
diff --git a/src/normal.c b/src/normal.c
index 7abd3fc..d169f26 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -1182,12 +1182,17 @@
kmsg = keep_msg;
keep_msg = NULL;
- /* showmode() will clear keep_msg, but we want to use it anyway */
+ // showmode() will clear keep_msg, but we want to use it anyway
update_screen(0);
- /* now reset it, otherwise it's put in the history again */
+ // now reset it, otherwise it's put in the history again
keep_msg = kmsg;
- msg_attr((char *)kmsg, keep_msg_attr);
- vim_free(kmsg);
+
+ kmsg = vim_strsave(keep_msg);
+ if (kmsg != NULL)
+ {
+ msg_attr((char *)kmsg, keep_msg_attr);
+ vim_free(kmsg);
+ }
}
setcursor();
cursor_on();
diff --git a/src/version.c b/src/version.c
index c6f60af..3161360 100644
--- a/src/version.c
+++ b/src/version.c
@@ -758,6 +758,8 @@
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 2018,
+/**/
2017,
/**/
2016,