From da50ca644c97b74d4c15166d8e11fd72cf67b952 Mon Sep 17 00:00:00 2001 From: Alexandre Janniaux Date: Fri, 25 Mar 2022 10:21:47 +0100 Subject: [PATCH] player: osd: fix memory leak on vlc_memstream Fix memstream stream being open but never closed when zero tracks were to be displayed to the OSD. The code was opening the vlc_memstream from the start but was freeing the pointer only when the close of the memstream succeeded AND the number of tracks was non-null. Instead, this patch reorder the code so that the vlc_memstream is allocated only when there is at least one track to display and early exit with the N/A OSD message otherwise. Then it tries to close the memstream and exit in case of error. Finally, the text is sent to the OSD and the pointer is freed. It was raising an ASAN leak report on test_src_player through the test_teletext test function. Fixes #26732 --- src/player/osd.c | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/src/player/osd.c b/src/player/osd.c index 64ecccc3d1..b08dcc88b6 100644 --- a/src/player/osd.c +++ b/src/player/osd.c @@ -210,7 +210,6 @@ vlc_player_osd_Tracks(vlc_player_t *player, vlc_es_id_t * const *selected, vlc_e const char *cat_name = es_format_category_to_string(cat); int tracks_count = 0; struct vlc_memstream stream; - vlc_memstream_open(&stream); for (size_t i = 0; selected[i] != NULL; i++) { @@ -225,23 +224,37 @@ vlc_player_osd_Tracks(vlc_player_t *player, vlc_es_id_t * const *selected, vlc_e if (unlikely(track == NULL)) continue; - if (tracks_count != 0) + /* Open the stream for the first track, and exit in case of error. + * On the next tracks, add comma to separate the track names. */ + if (tracks_count == 0) + { + if (vlc_memstream_open(&stream) != 0) + return; + } + else vlc_memstream_puts(&stream, ", "); + vlc_memstream_puts(&stream, track->name); tracks_count++; } - if (vlc_memstream_close(&stream) == 0 && tracks_count != 0) + if (tracks_count == 0) { - if (tracks_count == 1) - vlc_player_osd_Message(player, _("%s track: %s"), cat_name, - stream.ptr); - else - vlc_player_osd_Message(player, _("%s tracks: %s"), cat_name, - stream.ptr); - free(stream.ptr); - } else if (tracks_count == 0) vlc_player_osd_Message(player, _("%s track: %s"), cat_name, _("N/A")); + return; + } + + /* The vlc_memstream is opened only if tracks_count != 0. */ + if (vlc_memstream_close(&stream) != 0) + return; + + if (tracks_count == 1) + vlc_player_osd_Message(player, _("%s track: %s"), cat_name, + stream.ptr); + else + vlc_player_osd_Message(player, _("%s tracks: %s"), cat_name, + stream.ptr); + free(stream.ptr); } void