[vlc-devel] [PATCH] qt: playlist: fix stack overflow
Hugo Beauzée-Luyssen
hugo at beauzee.fr
Tue Nov 7 14:01:08 CET 2017
On Tue, Nov 7, 2017, at 09:53 AM, Romain Vimont wrote:
> The playlist tree may be arbitrary deep, so traversing it recursively
> may lead to stack overflow.
>
> Traverse it iteratively instead.
>
> Fixes #18376
> ---
> .../gui/qt/components/playlist/playlist_model.cpp | 30
> +++++++++++++++-------
> 1 file changed, 21 insertions(+), 9 deletions(-)
>
> diff --git a/modules/gui/qt/components/playlist/playlist_model.cpp
> b/modules/gui/qt/components/playlist/playlist_model.cpp
> index 2b6d0e1ccc..99e4c8f942 100644
> --- a/modules/gui/qt/components/playlist/playlist_model.cpp
> +++ b/modules/gui/qt/components/playlist/playlist_model.cpp
> @@ -41,6 +41,7 @@
> #include <assert.h>
> #include <QFont>
> #include <QAction>
> +#include <QStack>
>
> /*************************************************************************
> * Playlist model implementation
> @@ -518,20 +519,31 @@ PLItem *PLModel::findByPLId( PLItem *root, int i_id
> ) const
> if( root->id() == i_id )
> return root;
>
> - QList<AbstractPLItem *>::iterator it = root->children.begin();
> - while ( it != root->children.end() )
> + /* traverse the tree (in depth first) iteratively to avoid stack
> overflow */
> +
> + struct RemainingChildren {
> + QList<AbstractPLItem *>::const_iterator next;
> + QList<AbstractPLItem *>::const_iterator end;
> + };
> +
> + QStack<RemainingChildren> stack;
> + if( root->childCount() )
> + stack.push( {root->children.cbegin(), root->children.cend()} );
> +
> + while ( !stack.isEmpty() )
> {
> - PLItem *item = static_cast<PLItem *>(*it);
> + RemainingChildren &remainingChildren = stack.top();
> +
> + PLItem *item = static_cast<PLItem *>( *remainingChildren.next );
> if( item->id() == i_id )
> return item;
>
> + if( ++remainingChildren.next == remainingChildren.end )
> + /* there are no more children at this depth level */
> + stack.pop();
> +
> if( item->childCount() )
> - {
> - PLItem *childFound = findByPLId( item, i_id );
> - if( childFound )
> - return childFound;
> - }
> - ++it;
> + stack.push( {item->children.cbegin(), item->children.cend()}
> );
> }
> return NULL;
> }
> --
> 2.11.0
>
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel
LGTM
--
Hugo Beauzée-Luyssen
hugo at beauzee.fr
More information about the vlc-devel
mailing list