Subject: Re: [Boost-bugs] [Boost C++ Libraries] #12311: boost::filesystem::directory_iterator(const path& p) iteration to cause a std::terminate()
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2017-12-06 22:45:17
#12311: boost::filesystem::directory_iterator(const path& p) iteration to cause a
std::terminate()
---------------------------------+-------------------------
Reporter: florent.castelli@⦠| Owner: Beman Dawes
Type: Bugs | Status: new
Milestone: To Be Determined | Component: filesystem
Version: Boost 1.61.0 | Severity: Problem
Resolution: | Keywords:
---------------------------------+-------------------------
Comment (by Matthew DeLoera <mmdeloera@â¦>):
I'm dealing with this issue in 1.64. The description isn't accurate, and
there are actually multiple related issues.
'''Issue 1'''
* I'm working with the Win32 build BTW, but I expect all platforms are
broken.
* Referring to include/boost/filesystem/operations.hpp and
libs/filesystem/src/operations.cpp.
* Both the except/noexcept constructors of directory_iterator
(operations.hpp lines 901-905) call the same
detail::directory_iterator_construct, either passing 0 or &ec as normal
convention. This is fine.
* Win32's FindFileFirst typically first returns "." for me, so
directory_iterator_construct internally calls {{{it.increment(*ec)}}}.
'''This is NOT fine - you have just obfuscated the pointer with a
reference.'''
* So directory_iterator::increment '''always''' gets a system::error_code
&ec, but it's a bad reference if I had used the except constructor.
'''This is the piece that needs changed. Pass error_code*, not
error_code&.'''
* So even though obviously bad reference, non-NULL pointer is passed to
detail::directory_iterator_increment. If dir_itr_increment/FindNextFile
fails (and sets temp_ec), ec will always be non-NULL, so it will never
throw, but the {{{ec->assign}}} call will immediately burst into flames
(i.e. access violation). '''This is the actual crash, not an unexpected
exception as suggested above.'''
* FYI, I encountered this issue using URIs over SMB, rather than local
file system. I occasionally get successful FindFirstFile but failed
FindNextFile, but that's a tangent here.
'''Issue 2'''
* As the original description does mention, please remove BOOST_NOEXCEPT
from directory_iterator::increment, since it's obviously not true. Er that
is, it's only true right now because your throw is always skipped. But
once you fix that, you'll want to do this too.
'''Issue 3'''
* When you branch on ec==0 to either throw or not throw within
directory_iterator_increment (operations.cpp line 2401), you're always
obliterating the error code. Hence, when using non-exception
directory_iterator, it's impossible to distinguish between a valid empty
directory or internal iteration errors.
* Fix Issue 1.
* '''Now, instead throw or return temp_ec.''' Do NOT call BOOST_ERRNO! If
dir_itr_increment/FindNextFile failed, it grabs Win32 GetLastError into
temp_ec as it should, but then cleans up with Win32's FindClose, which
obviously clears the static errno. This 2nd call to BOOST_ERRNO is pretty
much guaranteed to return 0.
'''Issue 4'''
* In general operations.cpp calls GetLastError way more than it
needs/should. I suspect there are other places where a subsequent
GetLastError gets obliterated because of prior resource cleanup. I'd
suggest grep and confirm. This isn't quite so urgent, but please do
yourself a favor.
BTW, I'm willing to pitch in with these fixes if that might be helpful.
-- Ticket URL: <https://svn.boost.org/trac10/boost/ticket/12311#comment:3> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-12-06 22:52:10 UTC