summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2016-02-04 22:49:49 +0100
committerBram Moolenaar <Bram@vim.org>2016-02-04 22:49:49 +0100
commit4b6a6dcbe7bd13170c4884cc17acb1eac2c633d1 (patch)
tree9d02e26cd34ab973630872b8953d23d0fcb67a54
parenta8343c1808f2f268282f3030ce4adaf22e8ade54 (diff)
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.c25
-rw-r--r--src/eval.c5
-rw-r--r--src/json.c5
-rw-r--r--src/proto/channel.pro1
-rw-r--r--src/version.c2
5 files changed, 34 insertions, 4 deletions
diff --git a/src/channel.c b/src/channel.c
index 1290171949..0ae90a9638 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 892e14adac..f13486f227 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 f97d283120..b6fce02dc7 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 f53ac6680e..197cddf868 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 8611d49c18..1fbc721afa 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,