Fix using dangling pointer in iterator dtor in UTF-8 builds

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.
This commit is contained in:
Vadim Zeitlin 2023-03-27 18:51:42 +02:00
parent fab541a8ff
commit b1a30e96ae

View file

@ -274,6 +274,7 @@ public:
~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)
@ -285,7 +286,6 @@ public:
wxStringIteratorNode *m_prev{nullptr}, *m_next{nullptr};
private:
inline void clear();
inline void DoSet(const wxString *str,
wxStringImpl::const_iterator *citer,
wxStringImpl::iterator *iter);
@ -1213,16 +1213,24 @@ public:
{ 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)) {}