libstdc++: Enable debug assertions for filesystem directory iterators

Several member functions of filesystem::directory_iterator and
filesystem::recursive_directory_iterator currently dereference their
shared_ptr data member without checking for non-null. Because they use
operator-> and that function only uses _GLIBCXX_DEBUG_PEDASSERT rather
than __glibcxx_assert there is no assertion even when the library is
built with _GLIBCXX_ASSERTIONS defined. This means that dereferencing
invalid directory iterators gives an unhelpful segfault.

By using (*p). instead of p-> we get an assertion when the library is
built with _GLIBCXX_ASSERTIONS, with a "_M_get() != nullptr" message.

libstdc++-v3/ChangeLog:

	* src/c++17/fs_dir.cc (fs::directory_iterator::operator*): Use
	shared_ptr::operator* instead of shared_ptr::operator->.
	(fs::recursive_directory_iterator::options): Likewise.
	(fs::recursive_directory_iterator::depth): Likewise.
	(fs::recursive_directory_iterator::recursion_pending): Likewise.
	(fs::recursive_directory_iterator::operator*): Likewise.
	(fs::recursive_directory_iterator::disable_recursion_pending):
	Likewise.
This commit is contained in:
Jonathan Wakely 2024-10-28 17:55:02 +00:00 committed by Jonathan Wakely
parent 05e70ff921
commit f7979b8bfa
No known key found for this signature in database

View File

@ -230,7 +230,7 @@ directory_iterator(const path& p, directory_options options, error_code* ecptr)
const fs::directory_entry&
fs::directory_iterator::operator*() const noexcept
{
return _M_dir->entry;
return (*_M_dir).entry;
}
fs::directory_iterator&
@ -327,25 +327,25 @@ fs::recursive_directory_iterator::~recursive_directory_iterator() = default;
fs::directory_options
fs::recursive_directory_iterator::options() const noexcept
{
return _M_dirs->options;
return (*_M_dirs).options;
}
int
fs::recursive_directory_iterator::depth() const noexcept
{
return int(_M_dirs->size()) - 1;
return int((*_M_dirs).size()) - 1;
}
bool
fs::recursive_directory_iterator::recursion_pending() const noexcept
{
return _M_dirs->pending;
return (*_M_dirs).pending;
}
const fs::directory_entry&
fs::recursive_directory_iterator::operator*() const noexcept
{
return _M_dirs->top().entry;
return (*_M_dirs).top().entry;
}
fs::recursive_directory_iterator&
@ -453,7 +453,7 @@ fs::recursive_directory_iterator::pop()
void
fs::recursive_directory_iterator::disable_recursion_pending() noexcept
{
_M_dirs->pending = false;
(*_M_dirs).pending = false;
}
// Used to implement filesystem::remove_all.