Mercurial > vim
comparison src/ex_cmds.c @ 27449:b4c147ad4912 v8.2.4253
patch 8.2.4253: using freed memory when substitute with function call
Commit: https://github.com/vim/vim/commit/37f47958b8a2a44abc60614271d9537e7f14e51a
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Jan 29 14:21:51 2022 +0000
patch 8.2.4253: using freed memory when substitute with function call
Problem: Using freed memory when substitute uses a recursive function call.
Solution: Make a copy of the substitute text.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 29 Jan 2022 15:30:04 +0100 |
parents | 41e0dcf38521 |
children | fb4c30606b4a |
comparison
equal
deleted
inserted
replaced
27448:ca9bc0a44d8a | 27449:b4c147ad4912 |
---|---|
3685 subflags_T subflags_save; | 3685 subflags_T subflags_save; |
3686 #endif | 3686 #endif |
3687 int save_do_all; // remember user specified 'g' flag | 3687 int save_do_all; // remember user specified 'g' flag |
3688 int save_do_ask; // remember user specified 'c' flag | 3688 int save_do_ask; // remember user specified 'c' flag |
3689 char_u *pat = NULL, *sub = NULL; // init for GCC | 3689 char_u *pat = NULL, *sub = NULL; // init for GCC |
3690 char_u *sub_copy = NULL; | |
3690 int delimiter; | 3691 int delimiter; |
3691 int sublen; | 3692 int sublen; |
3692 int got_quit = FALSE; | 3693 int got_quit = FALSE; |
3693 int got_match = FALSE; | 3694 int got_match = FALSE; |
3694 int temp; | 3695 int temp; |
3978 regmatch.rmm_ic = FALSE; | 3979 regmatch.rmm_ic = FALSE; |
3979 | 3980 |
3980 sub_firstline = NULL; | 3981 sub_firstline = NULL; |
3981 | 3982 |
3982 /* | 3983 /* |
3983 * ~ in the substitute pattern is replaced with the old pattern. | 3984 * If the substitute pattern starts with "\=" then it's an expression. |
3984 * We do it here once to avoid it to be replaced over and over again. | 3985 * Make a copy, a recursive function may free it. |
3985 * But don't do it when it starts with "\=", then it's an expression. | 3986 * Otherwise, '~' in the substitute pattern is replaced with the old |
3987 * pattern. We do it here once to avoid it to be replaced over and over | |
3988 * again. | |
3986 */ | 3989 */ |
3987 if (!(sub[0] == '\\' && sub[1] == '=')) | 3990 if (sub[0] == '\\' && sub[1] == '=') |
3991 { | |
3992 sub = vim_strsave(sub); | |
3993 if (sub == NULL) | |
3994 return; | |
3995 sub_copy = sub; | |
3996 } | |
3997 else | |
3988 sub = regtilde(sub, magic_isset()); | 3998 sub = regtilde(sub, magic_isset()); |
3989 | 3999 |
3990 /* | 4000 /* |
3991 * Check for a match on each line. | 4001 * Check for a match on each line. |
3992 */ | 4002 */ |
4788 // Cursor position may require updating | 4798 // Cursor position may require updating |
4789 changed_window_setting(); | 4799 changed_window_setting(); |
4790 #endif | 4800 #endif |
4791 | 4801 |
4792 vim_regfree(regmatch.regprog); | 4802 vim_regfree(regmatch.regprog); |
4803 vim_free(sub_copy); | |
4793 | 4804 |
4794 // Restore the flag values, they can be used for ":&&". | 4805 // Restore the flag values, they can be used for ":&&". |
4795 subflags.do_all = save_do_all; | 4806 subflags.do_all = save_do_all; |
4796 subflags.do_ask = save_do_ask; | 4807 subflags.do_ask = save_do_ask; |
4797 } | 4808 } |