diff options
author | Bram Moolenaar <Bram@vim.org> | 2016-02-04 22:49:49 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2016-02-04 22:49:49 +0100 |
commit | 4b6a6dcbe7bd13170c4884cc17acb1eac2c633d1 (patch) | |
tree | 9d02e26cd34ab973630872b8953d23d0fcb67a54 | |
parent | a8343c1808f2f268282f3030ce4adaf22e8ade54 (diff) | |
download | vim-git-4b6a6dcbe7bd13170c4884cc17acb1eac2c633d1.tar.gz |
patch 7.4.1261v7.4.1261
Problem: Pending channel messages are garbage collected. Leaking memory in
ch_sendexpr(). Leaking memory for a decoded JSON string.
Solution: Mark the message list as used. Free the encoded JSON. Don't save
the JSON string.
-rw-r--r-- | src/channel.c | 25 | ||||
-rw-r--r-- | src/eval.c | 5 | ||||
-rw-r--r-- | src/json.c | 5 | ||||
-rw-r--r-- | src/proto/channel.pro | 1 | ||||
-rw-r--r-- | src/version.c | 2 |
5 files changed, 34 insertions, 4 deletions
diff --git a/src/channel.c b/src/channel.c index 129017194..0ae90a963 100644 --- a/src/channel.c +++ b/src/channel.c @@ -1315,4 +1315,29 @@ channel_parse_messages(void) return ret; } + int +set_ref_in_channel(int copyID) +{ + int i; + int abort = FALSE; + + for (i = 0; i < channel_count; ++i) + { + jsonq_T *head = &channels[i].ch_json_head; + jsonq_T *item = head->next; + + while (item != head) + { + list_T *l = item->value->vval.v_list; + + if (l->lv_copyID != copyID) + { + l->lv_copyID = copyID; + abort = abort || set_ref_in_list(l, copyID, NULL); + } + item = item->next; + } + } + return abort; +} #endif /* FEAT_CHANNEL */ diff --git a/src/eval.c b/src/eval.c index 892e14ada..f13486f22 100644 --- a/src/eval.c +++ b/src/eval.c @@ -6855,6 +6855,10 @@ garbage_collect(void) abort = abort || set_ref_in_python3(copyID); #endif +#ifdef FEAT_CHANNEL + abort = abort || set_ref_in_channel(copyID); +#endif + if (!abort) { /* @@ -9842,6 +9846,7 @@ f_ch_sendexpr(typval_T *argvars, typval_T *rettv) return; ch_idx = send_common(argvars, text, "sendexpr"); + vim_free(text); if (ch_idx >= 0) { if (channel_read_json_block(ch_idx, id, &listtv) == OK) diff --git a/src/json.c b/src/json.c index f97d28312..b6fce02dc 100644 --- a/src/json.c +++ b/src/json.c @@ -533,10 +533,7 @@ json_decode_string(js_read_T *reader, typval_T *res) if (res != NULL) { res->v_type = VAR_STRING; - if (ga.ga_data == NULL) - res->vval.v_string = NULL; - else - res->vval.v_string = vim_strsave(ga.ga_data); + res->vval.v_string = ga.ga_data; } return OK; } diff --git a/src/proto/channel.pro b/src/proto/channel.pro index f53ac6680..197cddf86 100644 --- a/src/proto/channel.pro +++ b/src/proto/channel.pro @@ -22,4 +22,5 @@ int channel_poll_check(int ret_in, void *fds_in); int channel_select_setup(int maxfd_in, void *rfds_in); int channel_select_check(int ret_in, void *rfds_in); int channel_parse_messages(void); +int set_ref_in_channel(int copyID); /* vim: set ft=c : */ diff --git a/src/version.c b/src/version.c index 8611d49c1..1fbc721af 100644 --- a/src/version.c +++ b/src/version.c @@ -743,6 +743,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1261, +/**/ 1260, /**/ 1259, |