Skip to content

Commit

Permalink
Fix using dangling pointer in iterator dtor in UTF-8 builds
Browse files Browse the repository at this point in the history
Destroying an iterator with a lifetime greater than that of the
associated string resulted in an invalid memory access due to using the
linked list of string iterators in the iterator dtor.

Fix this by clearing all the associated iterators when the string itself
is destroyed.

This fixes ASAN errors in wxDateTime::ParseDateTime() where "endTime"
const_iterator was destroyed after the destruction of the associated
"timestr" after successfully parsing the date.
  • Loading branch information
vadz committed Mar 27, 2023
1 parent fab541a commit b1a30e9
Showing 1 changed file with 11 additions and 3 deletions.
14 changes: 11 additions & 3 deletions include/wx/string.h
Expand Up @@ -274,6 +274,7 @@ class WXDLLIMPEXP_BASE wxStringIteratorNode
~wxStringIteratorNode()
{ clear(); }

inline void clear();
inline void set(const wxString *str, wxStringImpl::const_iterator *citer)
{ clear(); DoSet(str, citer, nullptr); }
inline void set(const wxString *str, wxStringImpl::iterator *iter)
Expand All @@ -285,7 +286,6 @@ class WXDLLIMPEXP_BASE wxStringIteratorNode
wxStringIteratorNode *m_prev{nullptr}, *m_next{nullptr};

private:
inline void clear();
inline void DoSet(const wxString *str,
wxStringImpl::const_iterator *citer,
wxStringImpl::iterator *iter);
Expand Down Expand Up @@ -1213,16 +1213,24 @@ class WXDLLIMPEXP_BASE wxString
{ assign(std::move(str), nLength); }


#if wxUSE_STRING_POS_CACHE
#if wxUSE_UNICODE_UTF8
~wxString()
{
#if wxUSE_STRING_POS_CACHE
// we need to invalidate our cache entry as another string could be
// recreated at the same address (unlikely, but still possible, with the
// heap-allocated strings but perfectly common with stack-allocated ones)
InvalidateCache();
}
#endif // wxUSE_STRING_POS_CACHE

// We also need to clear any still existing iterators pointing into this
// string, as otherwise clearing them later, when they're destroyed,
// would try to use a dangling string pointer stored in them.
while ( m_iterators.ptr )
m_iterators.ptr->clear();
}
#endif // wxUSE_UNICODE_UTF8

#if wxUSE_UNICODE_WCHAR
wxString(const std::wstring& str) : m_impl(str) {}
wxString(std::wstring&& str) noexcept : m_impl(std::move(str)) {}
Expand Down

0 comments on commit b1a30e9

Please sign in to comment.