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

+ +

1.51.0


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") {