diff --git a/doc/release_history.html b/doc/release_history.html index 074fc29..840c79e 100644 --- a/doc/release_history.html +++ b/doc/release_history.html @@ -62,6 +62,10 @@ recursive_directory_iterator equality testing has existed more than a dozen years. Nowadays test driven development would likely have detected the problem in early development. Sigh. +
create_directories() crashes when passed empty string as path,
+ from Samantha Ritter. Also affected create_directory(). Charles
+ Olivi submitted a pull request with some particularly helpful test cases.push_directory()internal logic so it is easier to
diff --git a/src/operations.cpp b/src/operations.cpp
index f34b076..1b3298e 100644
--- a/src/operations.cpp
+++ b/src/operations.cpp
@@ -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);
@@ -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();
@@ -1003,6 +1015,7 @@ namespace detail
p, error_code(errval, system_category())));
else
ec->assign(errval, system_category());
+
return false;
}
diff --git a/test/operations_test.cpp b/test/operations_test.cpp
index 09c28e0..400b12b 100644
--- a/test/operations_test.cpp
+++ b/test/operations_test.cpp
@@ -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
@@ -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
@@ -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);