https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99805

--- Comment #4 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Wow, this is tricksy.

The bug happens when parsing the string into a path. The path is split into
components and the offset of each component from the beginning of the string is
stored, so that parent_path() can efficiently erase the part of the native()
string that refers to the last component. The offset is calculated like this:

          for (auto& c : buf)
            {
              auto pos = c.str.data() - _M_pathname.data();
              ::new(output++) _Cmpt(c.str, c.type, pos);
              ++_M_cmpts._M_impl->_M_size;
            }

The bug is that for the COW std::string _M_pathname.data() causes the string to
be reallocated, and so changes the address at which the string is stored. So
the string_view c.str no longer refers to the same data as _M_pathname. We get
a bogus offset for the components, and when we try to remove the last component
to get the parent_path(), we don't remove anything from the string.

Reply via email to