Skip to content

Commit 4b6a6dc

Browse files
committed
patch 7.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.
1 parent a8343c1 commit 4b6a6dc

File tree

5 files changed

+34
-4
lines changed

5 files changed

+34
-4
lines changed

src/channel.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1315,4 +1315,29 @@ channel_parse_messages(void)
13151315
return ret;
13161316
}
13171317

1318+
int
1319+
set_ref_in_channel(int copyID)
1320+
{
1321+
int i;
1322+
int abort = FALSE;
1323+
1324+
for (i = 0; i < channel_count; ++i)
1325+
{
1326+
jsonq_T *head = &channels[i].ch_json_head;
1327+
jsonq_T *item = head->next;
1328+
1329+
while (item != head)
1330+
{
1331+
list_T *l = item->value->vval.v_list;
1332+
1333+
if (l->lv_copyID != copyID)
1334+
{
1335+
l->lv_copyID = copyID;
1336+
abort = abort || set_ref_in_list(l, copyID, NULL);
1337+
}
1338+
item = item->next;
1339+
}
1340+
}
1341+
return abort;
1342+
}
13181343
#endif /* FEAT_CHANNEL */

src/eval.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6855,6 +6855,10 @@ garbage_collect(void)
68556855
abort = abort || set_ref_in_python3(copyID);
68566856
#endif
68576857

6858+
#ifdef FEAT_CHANNEL
6859+
abort = abort || set_ref_in_channel(copyID);
6860+
#endif
6861+
68586862
if (!abort)
68596863
{
68606864
/*
@@ -9842,6 +9846,7 @@ f_ch_sendexpr(typval_T *argvars, typval_T *rettv)
98429846
return;
98439847

98449848
ch_idx = send_common(argvars, text, "sendexpr");
9849+
vim_free(text);
98459850
if (ch_idx >= 0)
98469851
{
98479852
if (channel_read_json_block(ch_idx, id, &listtv) == OK)

src/json.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -533,10 +533,7 @@ json_decode_string(js_read_T *reader, typval_T *res)
533533
if (res != NULL)
534534
{
535535
res->v_type = VAR_STRING;
536-
if (ga.ga_data == NULL)
537-
res->vval.v_string = NULL;
538-
else
539-
res->vval.v_string = vim_strsave(ga.ga_data);
536+
res->vval.v_string = ga.ga_data;
540537
}
541538
return OK;
542539
}

src/proto/channel.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,5 @@ int channel_poll_check(int ret_in, void *fds_in);
2222
int channel_select_setup(int maxfd_in, void *rfds_in);
2323
int channel_select_check(int ret_in, void *rfds_in);
2424
int channel_parse_messages(void);
25+
int set_ref_in_channel(int copyID);
2526
/* vim: set ft=c : */

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,8 @@ static char *(features[]) =
742742

743743
static int included_patches[] =
744744
{ /* Add new patch number below this line */
745+
/**/
746+
1261,
745747
/**/
746748
1260,
747749
/**/

0 commit comments

Comments
 (0)