Skip to content

Commit

Permalink
Fix #12495, create_directories() crashes when passed empty string as …
Browse files Browse the repository at this point in the history
…path, from Samantha Ritter. Also affected create_directory(). Charles Olivi submitted a pull request with some particularly helpful test cases.
  • Loading branch information
Beman committed Nov 23, 2016
1 parent 5004d7b commit 216720d
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 5 deletions.
4 changes: 4 additions & 0 deletions doc/release_history.html
Expand Up @@ -62,6 +62,10 @@ <h2>1.63.0</h2>
recursive_directory_iterator</code> equality testing has existed more than a
dozen years. Nowadays test driven development would likely have detected the
problem in early development. Sigh.</li>
<li>Fix <a href="https://svn.boost.org/trac/boost/ticket/12495">#12495</a>, <i>
<code>create_directories()</code> crashes when passed empty string as path</i>,
from Samantha Ritter. Also affected <code>create_directory()</code>. Charles
Olivi submitted a pull request with some particularly helpful test cases.</li>
<li>Fix broken link to
<a href="https://svn.boost.org/trac/boost/ticket/7506">#7506</a> in 1.60.0 Release History (Daniel Krügler).</li>
<li>Refactor <code>push_directory()</code>internal logic so it is easier to
Expand Down
15 changes: 14 additions & 1 deletion src/operations.cpp
Expand Up @@ -937,6 +937,17 @@ namespace detail
BOOST_FILESYSTEM_DECL
bool create_directories(const path& p, system::error_code* ec)
{
if (p.empty())
{
if (ec == 0)
BOOST_FILESYSTEM_THROW(filesystem_error(
"boost::filesystem::create_directories", p,
system::errc::make_error_code(system::errc::invalid_argument)));
else
ec->assign(system::errc::invalid_argument, system::generic_category());
return false;
}

if (p.filename_is_dot() || p.filename_is_dot_dot())
return create_directories(p.parent_path(), ec);

Expand Down Expand Up @@ -990,7 +1001,8 @@ namespace detail
// attempt to create directory failed
int errval(BOOST_ERRNO); // save reason for failure
error_code dummy;
if (errval == BOOST_ERROR_ALREADY_EXISTS && is_directory(p, dummy))

if (is_directory(p, dummy))
{
if (ec != 0)
ec->clear();
Expand All @@ -1003,6 +1015,7 @@ namespace detail
p, error_code(errval, system_category())));
else
ec->assign(errval, system_category());

return false;
}

Expand Down
43 changes: 39 additions & 4 deletions test/operations_test.cpp
Expand Up @@ -1038,8 +1038,26 @@ namespace
{
cout << "create_directory_tests..." << endl;

BOOST_TEST(!fs::create_directory("."));
BOOST_TEST(!fs::create_directory(".."));
error_code ec;
BOOST_TEST(!fs::create_directory("", ec));
BOOST_TEST(ec);

ec.clear();
BOOST_TEST(!fs::create_directory(" ", ec));
BOOST_TEST(ec);

ec.clear();
BOOST_TEST(!fs::create_directory("/", ec));
BOOST_TEST(!ec);
BOOST_TEST(fs::is_directory("/")); // this is a post-condition

ec.clear();
BOOST_TEST(!fs::create_directory(".", ec));
BOOST_TEST(!ec);

ec.clear();
BOOST_TEST(!fs::create_directory("..", ec));
BOOST_TEST(!ec);

// create a directory, then check it for consistency
// take extra care to report problems, since if this fails
Expand Down Expand Up @@ -1114,7 +1132,25 @@ namespace
{
cout << "create_directories_tests..." << endl;

BOOST_TEST(!fs::create_directories("/"));
error_code ec;
BOOST_TEST(!fs::create_directories("", ec));
BOOST_TEST(ec);

ec.clear();
BOOST_TEST(!fs::create_directories(" ", ec));
BOOST_TEST(ec);

ec.clear();
BOOST_TEST(!fs::create_directories("/", ec));
BOOST_TEST(!ec);

ec.clear();
BOOST_TEST(!fs::create_directories(".", ec));
BOOST_TEST(ec);

ec.clear();
BOOST_TEST(!fs::create_directories("..", ec));
BOOST_TEST(ec);

fs::path p = dir / "level1/." / "level2/./.." / "level3/";
// trailing "/.", "/./..", and "/" in the above elements test ticket #7258 and
Expand All @@ -1128,7 +1164,6 @@ namespace

if (fs::exists("/permissions_test"))
{
error_code ec;
BOOST_TEST(!fs::create_directories("/permissions_test", ec));
BOOST_TEST(!fs::create_directories("/permissions_test/another_directory", ec));
BOOST_TEST(ec);
Expand Down

0 comments on commit 216720d

Please sign in to comment.