From db7b970057c92127624ebafa7affaf77fdff6750 Mon Sep 17 00:00:00 2001 From: oni-link Date: Sat, 15 Aug 2015 11:36:14 +0200 Subject: rstream.c: Prevent stream closing if a read event is still queued. #3172 Processing a stream's output can be queued. If stream_close() is called before the queue is processed, the RBuffer containing the stream's data is freed and the next read event would try to access freed memory. To fix this behavior, use the stream's pending requests counter. --- src/nvim/event/rstream.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/event/rstream.c b/src/nvim/event/rstream.c index 0a720bb852..9f3fbc25ff 100644 --- a/src/nvim/event/rstream.c +++ b/src/nvim/event/rstream.c @@ -177,10 +177,25 @@ static void read_event(void **argv) bool eof = (uintptr_t)argv[2]; stream->read_cb(stream, stream->buffer, count, stream->data, eof); } + stream->pending_reqs--; + if (stream->closed && !stream->pending_reqs) { + stream_close_handle(stream); + } } static void invoke_read_cb(Stream *stream, size_t count, bool eof) { - CREATE_EVENT(stream->events, read_event, 3, stream, - (void *)(uintptr_t *)count, (void *)(uintptr_t)eof); + if (stream->closed) { + return; + } + + // Don't let the stream be closed before the event is processed. + stream->pending_reqs++; + + CREATE_EVENT(stream->events, + read_event, + 3, + stream, + (void *)(uintptr_t *)count, + (void *)(uintptr_t)eof); } -- cgit