From 08c11663d9a1d5430ef40deeddc7fa06a1f0ef02 Mon Sep 17 00:00:00 2001
From: Beman Dawes
Date: Tue, 28 Aug 2012 12:57:02 +0000
Subject: [PATCH] Fix #7239, Stack overflow when calling
create_directories(":D"). The reported problem was a symptom of an internal
bug that caused path::filename() and path::parent_path() to fail on Windows
for path(":"), and that in turn caused other functions that depend on
filename() or parent_path() to fail, such as create_directories().
[SVN r80279]
---
doc/release_history.html | 12 +++++++++++-
src/operations.cpp | 1 +
src/path.cpp | 2 +-
test/path_test.cpp | 21 +++++++++++++++++++++
4 files changed, 34 insertions(+), 2 deletions(-)
diff --git a/doc/release_history.html b/doc/release_history.html
index ffa2f5f..dac401c 100644
--- a/doc/release_history.html
+++ b/doc/release_history.html
@@ -36,6 +36,16 @@
+1.52.0
+
+ - Fix #7239, Stack
+ overflow when calling
create_directories(":D"). The reported
+ problem was a symptom of an internal bug that caused path::filename()
+ and path::parent_path() to fail on Windows for path(":"),
+ and that in turn caused other functions that depend on filename()
+ or parent_path() to fail, such as create_directories().
+
+
1.51.0
- Add begin() and end() non-member functions for directory_iterator and
@@ -181,7 +191,7 @@
Revised
-13 July, 2012
+28 August, 2012
© Copyright Beman Dawes, 2011
Use, modification, and distribution are subject to the Boost Software
License, Version 1.0. See
diff --git a/src/operations.cpp b/src/operations.cpp
index 16a336f..2aa4c2b 100644
--- a/src/operations.cpp
+++ b/src/operations.cpp
@@ -927,6 +927,7 @@ namespace detail
}
path parent = p.parent_path();
+ BOOST_ASSERT_MSG(parent != p, "internal error: p == p.parent_path()");
if (!parent.empty())
{
// determine if the parent exists
diff --git a/src/path.cpp b/src/path.cpp
index c740dec..6344bd3 100644
--- a/src/path.cpp
+++ b/src/path.cpp
@@ -510,7 +510,7 @@ namespace
size_type pos(str.find_last_of(separators, end_pos-1));
# ifdef BOOST_WINDOWS_API
- if (pos == string_type::npos)
+ if (pos == string_type::npos && end_pos > 1)
pos = str.find_last_of(colon, end_pos-2);
# endif
diff --git a/test/path_test.cpp b/test/path_test.cpp
index 0b2c80c..620aa0a 100644
--- a/test/path_test.cpp
+++ b/test/path_test.cpp
@@ -1117,6 +1117,27 @@ namespace
BOOST_TEST(p.has_parent_path());
BOOST_TEST(p.is_absolute());
+ // ticket 2739, infinite recursion leading to stack overflow, was caused
+ // by failure to handle this case correctly on Windows.
+ p = path(":");
+ PATH_TEST_EQ(p.parent_path().string(), "");
+ PATH_TEST_EQ(p.filename(), ":");
+ BOOST_TEST(!p.has_parent_path());
+ BOOST_TEST(p.has_filename());
+
+ // test some similar cases that both POSIX and Windows should handle identically
+ p = path("c:");
+ PATH_TEST_EQ(p.parent_path().string(), "");
+ PATH_TEST_EQ(p.filename(), "c:");
+ BOOST_TEST(!p.has_parent_path());
+ BOOST_TEST(p.has_filename());
+ p = path("cc:");
+ PATH_TEST_EQ(p.parent_path().string(), "");
+ PATH_TEST_EQ(p.filename(), "cc:");
+ BOOST_TEST(!p.has_parent_path());
+ BOOST_TEST(p.has_filename());
+
+ // Windows specific tests
if (platform == "Windows")
{