vim-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.
e5fbd73930
This commit is contained in:
Jan Edmund Lazo 2020-05-31 17:01:28 -04:00
parent 310a56d0a0
commit 44531928b3
No known key found for this signature in database
GPG Key ID: 64915E6E9F735B15
3 changed files with 12 additions and 10 deletions

View File

@ -203,7 +203,7 @@ EXTERN int msg_nowait INIT(= false); // don't wait for this msg
EXTERN int emsg_off INIT(= 0); // don't display errors for now, EXTERN int emsg_off INIT(= 0); // don't display errors for now,
// unless 'debug' is set. // unless 'debug' is set.
EXTERN int info_message INIT(= false); // printing informative message EXTERN int info_message INIT(= false); // printing informative message
EXTERN int msg_hist_off INIT(= false); // don't add messages to history EXTERN bool msg_hist_off INIT(= false); // don't add messages to history
EXTERN int need_clr_eos INIT(= false); // need to clear text before EXTERN int need_clr_eos INIT(= false); // need to clear text before
// displaying a message. // displaying a message.
EXTERN int emsg_skip INIT(= 0); // don't display errors for EXTERN int emsg_skip INIT(= 0); // don't display errors for

View File

@ -306,11 +306,6 @@ bool msg_attr_keep(char_u *s, int attr, bool keep, bool multiline)
add_msg_hist((const char *)s, -1, attr, multiline); add_msg_hist((const char *)s, -1, attr, multiline);
} }
/* When displaying keep_msg, don't let msg_start() free it, caller must do
* that. */
if (s == keep_msg)
keep_msg = NULL;
/* Truncate the message if needed. */ /* Truncate the message if needed. */
msg_start(); msg_start();
buf = msg_strtrunc(s, FALSE); buf = msg_strtrunc(s, FALSE);

View File

@ -621,6 +621,8 @@ static void normal_redraw_mode_message(NormalState *s)
update_screen(0); 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; keep_msg = kmsg;
kmsg = vim_strsave(keep_msg);
msg_attr((const char *)kmsg, keep_msg_attr); msg_attr((const char *)kmsg, keep_msg_attr);
xfree(kmsg); xfree(kmsg);
} }
@ -1265,10 +1267,15 @@ static void normal_redraw(NormalState *s)
// Display message after redraw. If an external message is still visible, // Display message after redraw. If an external message is still visible,
// it contains the kept message already. // it contains the kept message already.
if (keep_msg != NULL && !msg_ext_is_visible()) { if (keep_msg != NULL && !msg_ext_is_visible()) {
// msg_attr_keep() will set keep_msg to NULL, must free the string here. char_u *const p = vim_strsave(keep_msg);
// Don't reset keep_msg, msg_attr_keep() uses it to check for duplicates.
char *p = (char *)keep_msg; // msg_start() will set keep_msg to NULL, make a copy
msg_attr(p, keep_msg_attr); // 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((const char *)p, keep_msg_attr);
msg_hist_off = false;
xfree(p); xfree(p);
} }