From b8d259fb889e6946939bbb75bb63cb39a5f54929 Mon Sep 17 00:00:00 2001 From: Mike Crowe Date: Fri, 29 Jun 2018 14:43:16 +0100 Subject: [PATCH] directory_iterator_construct: Avoid provoking undefined behaviour The directory_iterator(const path& p) constructor calls detail::directory_iterator_construct passing nullptr (as 0) for the ec parameter. detail::directory_iterator_construct may call directory_iterator::increment(*ec) which dereferences the nullptr provoking undefined behaviour. On GCC, and probably many other compilers, it seems that this merely causes a null reference to be passed to directory_iterator::increment which in turn, turns it back into nullptr when calling detail::directory_iterator_increment which knows how to deal with the nullptr and is happy. Unfortunately, directory_iterator::increment(system::error_code& ec) is marked noexcept (unlike the version that takes no arguments) but detail::directory_iterator_increment throws exceptions when ec == nullptr. This results in std::terminate being called. The simplest way to fix this is for detail::directory_iterator_construct to just pass on the potentially-nullptr ec argument to detail::directory_iterator_increment rather than going via the potentially-noexcept directory_iterator::increment member function. (Discovered in the field with Boost 1.63 and a faulty disk. I managed to reproduce the problem by teaching dir_itr_increment to pretend that readdir_r_simulator returned an error when it saw a certain filename.) --- src/operations.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/operations.cpp b/src/operations.cpp index e6c0d99..4a38d0c 100644 --- a/src/operations.cpp +++ b/src/operations.cpp @@ -2341,7 +2341,7 @@ namespace detail && (filename.size()== 1 || (filename[1] == dot && filename.size()== 2))) - { it.increment(*ec); } + { detail::directory_iterator_increment(it, ec); } } }