Make LIB_ITEMS::ITERATOR operator++ and end() coherent

Previous operator++() could move LIB_ITEMS::ITERATOR past the iterator
returned by LIB_ITEMS::ITERATOR::end(), potentially leading to a
segfault.
This commit is contained in:
Maciej Suminski 2017-09-07 21:56:30 +02:00
parent 90668f9efb
commit 4cd319b0c7
1 changed files with 17 additions and 11 deletions

View File

@ -79,7 +79,7 @@ LIB_ITEMS_LIST::ITERATOR LIB_ITEMS_LIST::end( int aType ) const
} }
else // iterates over all items else // iterates over all items
{ {
// find a not empty container // find a not empty container, starting from the last type
auto i = m_data.rbegin(); auto i = m_data.rbegin();
while( i->second.empty() && i != m_data.rend() ) while( i->second.empty() && i != m_data.rend() )
@ -183,18 +183,24 @@ LIB_ITEMS_LIST::ITERATOR& LIB_ITEMS_LIST::ITERATOR::operator++()
if( m_it != (*m_parent)[m_type].end() ) if( m_it != (*m_parent)[m_type].end() )
++m_it; ++m_it;
if( m_it == (*m_parent)[m_type].end() && !m_filter && m_type < LAST_TYPE ) // should the iterator move to the next type?
if( m_it == (*m_parent)[m_type].end() && !m_filter )
{ {
// switch to the next type for not filtered iterator auto typeIt = m_parent->find( m_type );
do wxASSERT( typeIt != m_parent->end() );
++m_type;
while( ( !m_parent->count( m_type ) || (*m_parent)[m_type].empty() ) && m_type < LAST_TYPE );
// is it the real end of the list? // switch to the next type (look for a not empty container)
if( m_type == LAST_TYPE && (*m_parent)[LAST_TYPE].empty() ) do
m_it = (*m_parent)[LAST_TYPE].end(); ++typeIt;
else while( typeIt != m_parent->end() && typeIt->second.empty() );
m_it = (*m_parent)[m_type].begin();
// there is another not empty container, so make the iterator point to it,
// otherwise it means the iterator points to the last item
if( typeIt != m_parent->end() )
{
m_it = typeIt->second.begin();
m_type = typeIt->first;
}
} }
return *this; return *this;