From acd6e32983cd885c18f8232541dfe2b0b40f7f19 Mon Sep 17 00:00:00 2001 From: Přemysl Janouch Date: Tue, 24 Jan 2017 16:25:42 +0100 Subject: Fix memory leaks in uses of the MPD_SIMPLE macro --- nncmpp.c | 85 ++++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 51 insertions(+), 34 deletions(-) diff --git a/nncmpp.c b/nncmpp.c index 89cdbf0..fd5bf8c 100644 --- a/nncmpp.c +++ b/nncmpp.c @@ -1432,15 +1432,42 @@ g_actions[] = // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#define MPD_SIMPLE(...) \ -{ \ - if (c->state != MPD_CONNECTED) \ - break; \ - mpd_client_send_command (c, __VA_ARGS__, NULL); \ - mpd_client_add_task (c, NULL, NULL); \ - mpd_client_idle (c, 0); \ +static void +mpd_client_vsend_command (struct mpd_client *self, va_list ap) +{ + struct strv v; + strv_init (&v); + + const char *command; + while ((command = va_arg (ap, const char *))) + strv_append (&v, command); + mpd_client_send_commandv (self, v.vector); + strv_free (&v); } +/// Send a command to MPD without caring about the response +static bool mpd_client_send_simple (struct mpd_client *c, ...) + ATTRIBUTE_SENTINEL; + +static bool +mpd_client_send_simple (struct mpd_client *self, ...) +{ + if (self->state != MPD_CONNECTED) + return false; + + va_list ap; + va_start (ap, self); + mpd_client_vsend_command (self, ap); + va_end (ap); + + mpd_client_add_task (self, NULL, NULL); + mpd_client_idle (self, 0); + return true; +} + +#define MPD_SIMPLE(...) \ + mpd_client_send_simple (&g_ctx.client, __VA_ARGS__, NULL) + static bool app_process_action (enum action action) { @@ -1449,7 +1476,6 @@ app_process_action (enum action action) if (tab->on_action && tab->on_action (action)) return true; - struct mpd_client *c = &g_ctx.client; switch (action) { case ACTION_QUIT: @@ -1471,25 +1497,24 @@ app_process_action (enum action action) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case ACTION_MPD_PREVIOUS: - MPD_SIMPLE ("previous") + MPD_SIMPLE ("previous"); break; case ACTION_MPD_TOGGLE: - if (g_ctx.state == PLAYER_PLAYING) MPD_SIMPLE ("pause", "1") - else if (g_ctx.state == PLAYER_PAUSED) MPD_SIMPLE ("pause", "0") - else MPD_SIMPLE ("play") + if (g_ctx.state == PLAYER_PLAYING) MPD_SIMPLE ("pause", "1"); + else if (g_ctx.state == PLAYER_PAUSED) MPD_SIMPLE ("pause", "0"); + else MPD_SIMPLE ("play"); break; case ACTION_MPD_STOP: - MPD_SIMPLE ("stop") + MPD_SIMPLE ("stop"); break; case ACTION_MPD_NEXT: - MPD_SIMPLE ("next") + MPD_SIMPLE ("next"); break; case ACTION_MPD_VOLUME_UP: if (g_ctx.volume >= 0) { char *volume = xstrdup_printf ("%d", MIN (100, g_ctx.volume + 10)); - // FIXME: if this breaks, it leaks "volume" - MPD_SIMPLE ("setvol", volume) + MPD_SIMPLE ("setvol", volume); free (volume); } break; @@ -1497,16 +1522,15 @@ app_process_action (enum action action) if (g_ctx.volume >= 0) { char *volume = xstrdup_printf ("%d", MAX (0, g_ctx.volume - 10)); - // FIXME: if this breaks, it leaks "volume" - MPD_SIMPLE ("setvol", volume) + MPD_SIMPLE ("setvol", volume); free (volume); } break; // TODO: relative seeks #if 0 - MPD_SIMPLE (forward, "seekcur", "+10", NULL) - MPD_SIMPLE (backward, "seekcur", "-10", NULL) + FORWARD: MPD_SIMPLE ("seekcur", "+10"); + BACKWARD: MPD_SIMPLE ("seekcur", "-10"); #endif // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1587,15 +1611,11 @@ app_process_left_mouse_click (int line, int column, bool double_click) return false; float position = (float) gauge_offset / g_ctx.gauge_width; - struct mpd_client *c = &g_ctx.client; - if (c->state == MPD_CONNECTED && g_ctx.song_duration >= 1) + if (g_ctx.song_duration >= 1) { char *where = xstrdup_printf ("%f", position * g_ctx.song_duration); - mpd_client_send_command (c, "seekcur", where, NULL); + MPD_SIMPLE ("seekcur", where); free (where); - - mpd_client_add_task (c, NULL, NULL); - mpd_client_idle (c, 0); } } else if (line == g_ctx.header_height - 1) @@ -1795,20 +1815,17 @@ current_tab_on_action (enum action action) if (self->item_selected < 0) return false; - struct mpd_client *c = &g_ctx.client; switch (action) { char *song; case ACTION_CHOOSE: song = xstrdup_printf ("%d", self->item_selected); - // FIXME: if this breaks, it leaks "volume" - MPD_SIMPLE ("play", song) + MPD_SIMPLE ("play", song); free (song); return true; case ACTION_DELETE: song = xstrdup_printf ("%d", self->item_selected); - // FIXME: if this breaks, it leaks "volume" - MPD_SIMPLE ("delete", song) + MPD_SIMPLE ("delete", song); free (song); return true; default: @@ -2027,7 +2044,7 @@ library_tab_on_action (enum action action) case LIBRARY_ROOT: case LIBRARY_UP: case LIBRARY_DIR: library_tab_reload (x.path); break; - case LIBRARY_FILE: MPD_SIMPLE ("add", x.path) break; + case LIBRARY_FILE: MPD_SIMPLE ("add", x.path); break; default: hard_assert (!"invalid item type"); } return true; @@ -2037,13 +2054,13 @@ library_tab_on_action (enum action action) break; MPD_SIMPLE ("clear"); - MPD_SIMPLE ("add", x.path) + MPD_SIMPLE ("add", x.path); return true; case ACTION_MPD_ADD: if (x.type != LIBRARY_DIR && x.type != LIBRARY_FILE) break; - MPD_SIMPLE ("add", x.path) + MPD_SIMPLE ("add", x.path); return true; default: break; -- cgit v1.2.3-70-g09d2