[vlc-commits] ncurses: identify playlist item by input item
Rémi Denis-Courmont
git at videolan.org
Sat Nov 19 22:26:38 CET 2016
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sat Nov 19 19:01:20 2016 +0200| [ea5fe6789dcff56b7ffd080d18b1283f5250fb7c] | committer: Rémi Denis-Courmont
ncurses: identify playlist item by input item
This fixes a whole lot of use-after-free bugs.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=ea5fe6789dcff56b7ffd080d18b1283f5250fb7c
---
modules/gui/ncurses.c | 76 +++++++++++++++++++++++++++++----------------------
1 file changed, 43 insertions(+), 33 deletions(-)
diff --git a/modules/gui/ncurses.c b/modules/gui/ncurses.c
index 34afe34..35f9842 100644
--- a/modules/gui/ncurses.c
+++ b/modules/gui/ncurses.c
@@ -174,8 +174,8 @@ struct dir_entry_t
struct pl_item_t
{
- playlist_item_t *item;
- char *display;
+ input_item_t *item;
+ char *display;
};
struct intf_sys_t
@@ -349,6 +349,8 @@ static void PlaylistDestroy(intf_sys_t *sys)
{
while (sys->plist_entries) {
struct pl_item_t *p_pl_item = sys->plist[--sys->plist_entries];
+
+ input_item_Release(p_pl_item->item);
free(p_pl_item->display);
free(p_pl_item);
}
@@ -366,19 +368,16 @@ static bool PlaylistAddChild(intf_sys_t *sys, playlist_item_t *p_child,
if (!name || !p_pl_item)
goto error;
- p_pl_item->item = p_child;
-
if (c && *c)
ret = asprintf(&p_pl_item->display, "%s%c-%s", c, d, name);
else
ret = asprintf(&p_pl_item->display, " %s", name);
-
- free(name);
- name = NULL;
-
if (ret == -1)
goto error;
+ free(name);
+ p_pl_item->item = input_item_Hold(p_child->p_input);
+
INSERT_ELEM(sys->plist, sys->plist_entries,
sys->plist_entries, p_pl_item);
@@ -488,7 +487,10 @@ static void SearchPlaylist(intf_sys_t *sys)
static inline bool IsIndex(intf_sys_t *sys, playlist_t *p_playlist, int i)
{
- playlist_item_t *item = sys->plist[i]->item;
+ input_item_t *input = sys->plist[i]->item;
+ playlist_item_t *item = playlist_ItemGetByInput(p_playlist, input);
+ if (unlikely(item == NULL))
+ return false;
PL_ASSERT_LOCKED;
@@ -500,8 +502,8 @@ static inline bool IsIndex(intf_sys_t *sys, playlist_t *p_playlist, int i)
vlc_mutex_unlock(&sys->pl_lock);
playlist_item_t *p_played_item = playlist_CurrentPlayingItem(p_playlist);
- if (p_played_item && item->p_input && p_played_item->p_input)
- return item->p_input == p_played_item->p_input;
+ if (p_played_item != NULL)
+ return input == p_played_item->p_input;
return false;
}
@@ -980,19 +982,19 @@ static int DrawPlaylist(intf_thread_t *intf, input_thread_t *input)
for (int i = 0; i < sys->plist_entries; i++) {
char c;
- playlist_item_t *current_item;
- playlist_item_t *item = sys->plist[i]->item;
+ playlist_item_t *current;
+ input_item_t *input = sys->plist[i]->item;
vlc_mutex_lock(&sys->pl_lock);
playlist_item_t *node = sys->node;
vlc_mutex_unlock(&sys->pl_lock);
PL_LOCK;
- assert(item);
- current_item = playlist_CurrentPlayingItem(p_playlist);
- if ((node && item->p_input == node->p_input) ||
- (!node && current_item && item->p_input == current_item->p_input))
+ current = playlist_CurrentPlayingItem(p_playlist);
+
+ if ((node && input == node->p_input) ||
+ (!node && current != NULL && input == current->p_input))
c = '*';
- else if (item == node || current_item == item)
+ else if (current != NULL && current->p_input == input)
c = '>';
else
c = ' ';
@@ -1336,7 +1338,6 @@ static bool HandlePlaylistKey(intf_thread_t *intf, int key)
{
intf_sys_t *sys = intf->p_sys;
playlist_t *p_playlist = pl_Get(intf);
- struct pl_item_t *p_pl_item;
switch(key)
{
@@ -1372,13 +1373,14 @@ static bool HandlePlaylistKey(intf_thread_t *intf, int key)
case 0x7f:
case KEY_DC:
{
+ input_item_t *input = sys->plist[sys->box_idx]->item;
playlist_item_t *item;
PL_LOCK;
-#warning FIXME
- item = sys->plist[sys->box_idx]->item;
+ item = playlist_ItemGetByInput(p_playlist, input);
playlist_NodeDelete(p_playlist, item, false);
PL_UNLOCK;
+
vlc_mutex_lock(&sys->pl_lock);
if (sys->box_idx >= sys->box_lines_total - 1)
sys->box_idx = sys->box_lines_total - 2;
@@ -1390,35 +1392,43 @@ static bool HandlePlaylistKey(intf_thread_t *intf, int key)
case KEY_ENTER:
case '\r':
case '\n':
- if (!(p_pl_item = sys->plist[sys->box_idx]))
+ {
+ struct pl_item_t *p_pl_item = sys->plist[sys->box_idx];
+ if (p_pl_item == NULL)
return false;
- if (p_pl_item->item->i_children) {
- playlist_item_t *item, *p_parent = p_pl_item->item;
- if (p_parent->i_children == -1) {
- item = p_parent;
+ playlist_item_t *item;
- while (p_parent->p_parent)
- p_parent = p_parent->p_parent;
+ playlist_Lock(p_playlist);
+ item = playlist_ItemGetByInput(p_playlist, p_pl_item->item);
+
+ if (item->i_children) {
+ playlist_item_t *parent = item;
+
+ if (item->i_children == -1) {
+ while (parent->p_parent != NULL)
+ parent = parent->p_parent;
} else {
vlc_mutex_lock(&sys->pl_lock);
- sys->node = p_parent;
+ sys->node = parent;
vlc_mutex_unlock(&sys->pl_lock);
item = NULL;
}
- playlist_Control(p_playlist, PLAYLIST_VIEWPLAY, pl_Unlocked,
- p_parent, item);
+ playlist_Control(p_playlist, PLAYLIST_VIEWPLAY, true,
+ parent, item);
} else { /* We only want to set the current node */
- playlist_Stop(p_playlist);
+ playlist_Control(p_playlist, PLAYLIST_STOP, true);
vlc_mutex_lock(&sys->pl_lock);
- sys->node = p_pl_item->item;
+ sys->node = item;
vlc_mutex_unlock(&sys->pl_lock);
}
+ playlist_Unlock(p_playlist);
sys->plidx_follow = true;
return true;
}
+ }
return false;
}
More information about the vlc-commits
mailing list