Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r76541 - in trunk: boost/filesystem/v3 libs/filesystem/v3/src libs/filesystem/v3/test libs/filesystem/v3/test/msvc10
From: bdawes_at_[hidden]
Date: 2012-01-16 10:59:29


Author: bemandawes
Date: 2012-01-16 10:59:27 EST (Mon, 16 Jan 2012)
New Revision: 76541
URL: http://svn.boost.org/trac/boost/changeset/76541

Log:
Add test cases and fixes for class path errors when assignment or appends used self or portion of self as source. Fixes ticket #3714
Text files modified:
   trunk/boost/filesystem/v3/path.hpp | 48 ++++++++++++++++++++++++++++----------
   trunk/boost/filesystem/v3/path_traits.hpp | 2
   trunk/libs/filesystem/v3/src/path.cpp | 39 ++++++++++++++++++++++++++++---
   trunk/libs/filesystem/v3/test/msvc10/filesystem-v3.sln | 6 ++++
   trunk/libs/filesystem/v3/test/path_test.cpp | 49 ++++++++++++++++++++++++++++++++++++++++
   5 files changed, 126 insertions(+), 18 deletions(-)

Modified: trunk/boost/filesystem/v3/path.hpp
==============================================================================
--- trunk/boost/filesystem/v3/path.hpp (original)
+++ trunk/boost/filesystem/v3/path.hpp 2012-01-16 10:59:27 EST (Mon, 16 Jan 2012)
@@ -183,6 +183,12 @@
       return *this;
     }
 
+ path& operator=(const value_type* ptr) // required in case ptr overlaps *this
+ {
+ m_pathname = ptr;
+ return *this;
+ }
+
     template <class Source>
       typename boost::enable_if<path_traits::is_pathable<
         typename boost::decay<Source>::type>, path&>::type
@@ -193,6 +199,12 @@
       return *this;
     }
 
+ path& assign(const value_type* ptr, const codecvt_type&) // required in case ptr overlaps *this
+ {
+ m_pathname = ptr;
+ return *this;
+ }
+
     template <class Source>
     path& assign(Source const& source, const codecvt_type& cvt)
     {
@@ -227,6 +239,8 @@
 
     path& operator/=(const path& p);
 
+ path& operator/=(const value_type* ptr);
+
     template <class Source>
       typename boost::enable_if<path_traits::is_pathable<
         typename boost::decay<Source>::type>, path&>::type
@@ -235,6 +249,12 @@
       return append(source, codecvt());
     }
 
+ path& append(const value_type* ptr, const codecvt_type&) // required in case ptr overlaps *this
+ {
+ this->operator/=(ptr);
+ return *this;
+ }
+
     template <class Source>
     path& append(Source const& source, const codecvt_type& cvt);
 
@@ -378,6 +398,16 @@
     }
     bool is_relative() const { return !is_absolute(); }
 
+ // ----- iterators -----
+
+ class iterator;
+ typedef iterator const_iterator;
+
+ iterator begin() const;
+ iterator end() const;
+
+ // ----- static members -----
+
     // ----- imbue -----
 
     static std::locale imbue(const std::locale& loc);
@@ -389,14 +419,6 @@
       return *wchar_t_codecvt_facet();
     }
 
- // ----- iterators -----
-
- class iterator;
- typedef iterator const_iterator;
-
- iterator begin() const;
- iterator end() const;
-
     // ----- deprecated functions -----
 
 # if defined(BOOST_FILESYSTEM_DEPRECATED) && defined(BOOST_FILESYSTEM_NO_DEPRECATED)
@@ -650,14 +672,14 @@
   }
 
   template <class Source>
- path& path::append(Source const & source, const codecvt_type& cvt)
+ path& path::append(Source const& source, const codecvt_type& cvt)
   {
     if (path_traits::empty(source))
       return *this;
- string_type::size_type sep_pos(m_append_separator_if_needed());
- path_traits::dispatch(source, m_pathname, cvt);
- if (sep_pos)
- m_erase_redundant_separator(sep_pos);
+ string_type::size_type sep_pos(m_append_separator_if_needed());
+ path_traits::dispatch(source, m_pathname, cvt);
+ if (sep_pos)
+ m_erase_redundant_separator(sep_pos);
     return *this;
   }
 

Modified: trunk/boost/filesystem/v3/path_traits.hpp
==============================================================================
--- trunk/boost/filesystem/v3/path_traits.hpp (original)
+++ trunk/boost/filesystem/v3/path_traits.hpp 2012-01-16 10:59:27 EST (Mon, 16 Jan 2012)
@@ -164,7 +164,7 @@
     to += from;
   }
 
- // Source dispatch
+ // Source dispatch -----------------------------------------------------------------//
 
   // contiguous containers
   template <class U> inline

Modified: trunk/libs/filesystem/v3/src/path.cpp
==============================================================================
--- trunk/libs/filesystem/v3/src/path.cpp (original)
+++ trunk/libs/filesystem/v3/src/path.cpp 2012-01-16 10:59:27 EST (Mon, 16 Jan 2012)
@@ -145,13 +145,44 @@
 namespace filesystem3
 {
 
- path & path::operator/=(const path & p)
+ path& path::operator/=(const path& p)
   {
     if (p.empty())
       return *this;
- if (!is_separator(*p.m_pathname.begin()))
- m_append_separator_if_needed();
- m_pathname += p.m_pathname;
+ if (this == &p) // self-append
+ {
+ path rhs(p);
+ if (!is_separator(rhs.m_pathname[0]))
+ m_append_separator_if_needed();
+ m_pathname += rhs.m_pathname;
+ }
+ else
+ {
+ if (!is_separator(*p.m_pathname.begin()))
+ m_append_separator_if_needed();
+ m_pathname += p.m_pathname;
+ }
+ return *this;
+ }
+
+ path& path::operator/=(const value_type* ptr)
+ {
+ if (!*ptr)
+ return *this;
+ if (ptr >= m_pathname.data()
+ && ptr < m_pathname.data() + m_pathname.size()) // overlapping source
+ {
+ path rhs(ptr);
+ if (!is_separator(rhs.m_pathname[0]))
+ m_append_separator_if_needed();
+ m_pathname += rhs.m_pathname;
+ }
+ else
+ {
+ if (!is_separator(*ptr))
+ m_append_separator_if_needed();
+ m_pathname += ptr;
+ }
     return *this;
   }
 

Modified: trunk/libs/filesystem/v3/test/msvc10/filesystem-v3.sln
==============================================================================
--- trunk/libs/filesystem/v3/test/msvc10/filesystem-v3.sln (original)
+++ trunk/libs/filesystem/v3/test/msvc10/filesystem-v3.sln 2012-01-16 10:59:27 EST (Mon, 16 Jan 2012)
@@ -79,6 +79,8 @@
                 {FFD738F7-96F0-445C-81EA-551665EF53D1} = {FFD738F7-96F0-445C-81EA-551665EF53D1}
         EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "thread_test", "thread_test\thread_test.vcxproj", "{20E2805D-9634-46CE-B979-21CCBBD16EA3}"
+EndProject
 Global
         GlobalSection(SolutionConfigurationPlatforms) = preSolution
                 Debug|Win32 = Debug|Win32
@@ -177,6 +179,10 @@
                 {B1FA4137-7B08-4113-9EC0-F3BAFEFBE2B7}.Debug|Win32.Build.0 = Debug|Win32
                 {B1FA4137-7B08-4113-9EC0-F3BAFEFBE2B7}.Release|Win32.ActiveCfg = Release|Win32
                 {B1FA4137-7B08-4113-9EC0-F3BAFEFBE2B7}.Release|Win32.Build.0 = Release|Win32
+ {20E2805D-9634-46CE-B979-21CCBBD16EA3}.Debug|Win32.ActiveCfg = Debug|Win32
+ {20E2805D-9634-46CE-B979-21CCBBD16EA3}.Debug|Win32.Build.0 = Debug|Win32
+ {20E2805D-9634-46CE-B979-21CCBBD16EA3}.Release|Win32.ActiveCfg = Release|Win32
+ {20E2805D-9634-46CE-B979-21CCBBD16EA3}.Release|Win32.Build.0 = Release|Win32
         EndGlobalSection
         GlobalSection(SolutionProperties) = preSolution
                 HideSolutionNode = FALSE

Modified: trunk/libs/filesystem/v3/test/path_test.cpp
==============================================================================
--- trunk/libs/filesystem/v3/test/path_test.cpp (original)
+++ trunk/libs/filesystem/v3/test/path_test.cpp 2012-01-16 10:59:27 EST (Mon, 16 Jan 2012)
@@ -57,6 +57,12 @@
 #include <boost/detail/lightweight_test.hpp>
 #include <boost/detail/lightweight_main.hpp>
 
+#ifdef BOOST_WINDOWS_API
+# define BOOST_DIR_SEP "\\"
+#else
+# define BOOST_DIR_SEP "/"
+#endif
+
 #define PATH_CHECK(a, b) check(a, b, __FILE__, __LINE__)
 #define CHECK_EQUAL(a,b) check_equal(a, b, __FILE__, __LINE__)
 
@@ -1520,6 +1526,48 @@
 
   }
 
+// self_assign_and_append_tests ------------------------------------------------------//
+
+ void self_assign_and_append_tests()
+ {
+ std::cout << "self_assign_and_append_tests..." << std::endl;
+
+ path p;
+
+ p = "snafubar";
+ BOOST_TEST_EQ(p = p, "snafubar");
+
+ p = "snafubar";
+ p = p.c_str();
+ BOOST_TEST_EQ(p, "snafubar");
+
+ p = "snafubar";
+ p.assign(p.c_str(), path::codecvt());
+ BOOST_TEST_EQ(p, "snafubar");
+
+ p = "snafubar";
+ BOOST_TEST_EQ(p = p.c_str()+5, "bar");
+
+ p = "snafubar";
+ BOOST_TEST_EQ(p.assign(p.c_str() + 5, p.c_str() + 7), "ba");
+
+ p = "snafubar";
+ p /= p;
+ BOOST_TEST_EQ(p, "snafubar" BOOST_DIR_SEP "snafubar");
+
+ p = "snafubar";
+ p /= p.c_str();
+ BOOST_TEST_EQ(p, "snafubar" BOOST_DIR_SEP "snafubar");
+
+ p = "snafubar";
+ p.append(p.c_str(), path::codecvt());
+ BOOST_TEST_EQ(p, "snafubar" BOOST_DIR_SEP "snafubar");
+
+ p = "snafubar";
+ BOOST_TEST_EQ(p.append(p.c_str() + 5, p.c_str() + 7), "snafubar" BOOST_DIR_SEP "ba");
+ }
+
+
   // name_function_tests -------------------------------------------------------------//
 
   void name_function_tests()
@@ -1678,6 +1726,7 @@
 
   construction_tests();
   append_tests();
+ self_assign_and_append_tests();
   overload_tests();
   query_and_decomposition_tests();
   composition_tests();


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk