Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r62695 - in trunk: boost/algorithm/string/detail libs/algorithm/string/test
From: steven_at_[hidden]
Date: 2010-06-09 19:04:26


Author: steven_watanabe
Date: 2010-06-09 19:04:24 EDT (Wed, 09 Jun 2010)
New Revision: 62695
URL: http://svn.boost.org/trac/boost/changeset/62695

Log:
Avoid calling the formatter with an invalid match. Fixes #2777
Text files modified:
   trunk/boost/algorithm/string/detail/find_format.hpp | 44 +++++++++++------
   trunk/boost/algorithm/string/detail/find_format_all.hpp | 50 ++++++++++++--------
   trunk/boost/algorithm/string/detail/find_format_store.hpp | 13 ++++
   trunk/libs/algorithm/string/test/find_format_test.cpp | 98 +++++++++++++++++++++++++++++++--------
   4 files changed, 147 insertions(+), 58 deletions(-)

Modified: trunk/boost/algorithm/string/detail/find_format.hpp
==============================================================================
--- trunk/boost/algorithm/string/detail/find_format.hpp (original)
+++ trunk/boost/algorithm/string/detail/find_format.hpp 2010-06-09 19:04:24 EDT (Wed, 09 Jun 2010)
@@ -74,13 +74,17 @@
                 const InputT& Input,
                 FormatterT Formatter,
                 const FindResultT& FindResult )
- {
- return ::boost::algorithm::detail::find_format_copy_impl2(
- Output,
- Input,
- Formatter,
- FindResult,
- Formatter(FindResult) );
+ {
+ if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) {
+ return ::boost::algorithm::detail::find_format_copy_impl2(
+ Output,
+ Input,
+ Formatter,
+ FindResult,
+ Formatter(FindResult) );
+ } else {
+ return std::copy( ::boost::begin(Input), ::boost::end(Input), Output );
+ }
             }
 
  
@@ -132,11 +136,15 @@
                 FormatterT Formatter,
                 const FindResultT& FindResult)
             {
- return ::boost::algorithm::detail::find_format_copy_impl2(
- Input,
- Formatter,
- FindResult,
- Formatter(FindResult) );
+ if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) {
+ return ::boost::algorithm::detail::find_format_copy_impl2(
+ Input,
+ Formatter,
+ FindResult,
+ Formatter(FindResult) );
+ } else {
+ return Input;
+ }
             }
 
  // replace implementation ----------------------------------------------------//
@@ -180,11 +188,13 @@
                 FormatterT Formatter,
                 const FindResultT& FindResult)
             {
- ::boost::algorithm::detail::find_format_impl2(
- Input,
- Formatter,
- FindResult,
- Formatter(FindResult) );
+ if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) {
+ ::boost::algorithm::detail::find_format_impl2(
+ Input,
+ Formatter,
+ FindResult,
+ Formatter(FindResult) );
+ }
             }
 
         } // namespace detail

Modified: trunk/boost/algorithm/string/detail/find_format_all.hpp
==============================================================================
--- trunk/boost/algorithm/string/detail/find_format_all.hpp (original)
+++ trunk/boost/algorithm/string/detail/find_format_all.hpp 2010-06-09 19:04:24 EDT (Wed, 09 Jun 2010)
@@ -84,14 +84,18 @@
                 FinderT Finder,
                 FormatterT Formatter,
                 const FindResultT& FindResult )
- {
- return ::boost::algorithm::detail::find_format_all_copy_impl2(
- Output,
- Input,
- Finder,
- Formatter,
- FindResult,
- Formatter(FindResult) );
+ {
+ if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) {
+ return ::boost::algorithm::detail::find_format_all_copy_impl2(
+ Output,
+ Input,
+ Finder,
+ Formatter,
+ FindResult,
+ Formatter(FindResult) );
+ } else {
+ return std::copy( ::boost::begin(Input), ::boost::end(Input), Output );
+ }
             }
 
  // find_format_all_copy implementation ----------------------------------------------//
@@ -156,12 +160,16 @@
                 FormatterT Formatter,
                 const FindResultT& FindResult)
             {
- return ::boost::algorithm::detail::find_format_all_copy_impl2(
- Input,
- Finder,
- Formatter,
- FindResult,
- Formatter(FindResult) );
+ if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) {
+ return ::boost::algorithm::detail::find_format_all_copy_impl2(
+ Input,
+ Finder,
+ Formatter,
+ FindResult,
+ Formatter(FindResult) );
+ } else {
+ return Input;
+ }
             }
 
  // find_format_all implementation ------------------------------------------------//
@@ -248,12 +256,14 @@
                 FormatterT Formatter,
                 FindResultT FindResult)
             {
- ::boost::algorithm::detail::find_format_all_impl2(
- Input,
- Finder,
- Formatter,
- FindResult,
- Formatter(FindResult) );
+ if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) {
+ ::boost::algorithm::detail::find_format_all_impl2(
+ Input,
+ Finder,
+ Formatter,
+ FindResult,
+ Formatter(FindResult) );
+ }
             }
 
         } // namespace detail

Modified: trunk/boost/algorithm/string/detail/find_format_store.hpp
==============================================================================
--- trunk/boost/algorithm/string/detail/find_format_store.hpp (original)
+++ trunk/boost/algorithm/string/detail/find_format_store.hpp 2010-06-09 19:04:24 EDT (Wed, 09 Jun 2010)
@@ -52,7 +52,9 @@
                 find_format_store& operator=( FindResultT FindResult )
                 {
                     iterator_range<ForwardIteratorT>::operator=(FindResult);
- m_FormatResult=m_Formatter(FindResult);
+ if( !this->empty() ) {
+ m_FormatResult=m_Formatter(FindResult);
+ }
                     
                     return *this;
                 }
@@ -68,6 +70,15 @@
                 const formatter_type& m_Formatter;
             };
 
+ template<typename InputT, typename FindResultT>
+ bool check_find_result(InputT& Input, FindResultT& FindResult)
+ {
+ typedef BOOST_STRING_TYPENAME
+ range_const_iterator<InputT>::type input_iterator_type;
+ iterator_range<input_iterator_type> ResultRange(FindResult);
+ return !ResultRange.empty();
+ }
+
 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
 #pragma warning(pop)
 #endif

Modified: trunk/libs/algorithm/string/test/find_format_test.cpp
==============================================================================
--- trunk/libs/algorithm/string/test/find_format_test.cpp (original)
+++ trunk/libs/algorithm/string/test/find_format_test.cpp 2010-06-09 19:04:24 EDT (Wed, 09 Jun 2010)
@@ -16,6 +16,31 @@
 
 #include <boost/test/test_tools.hpp>
 
+// We're only using const_formatter.
+template<class Formatter>
+struct formatter_result {
+ typedef boost::iterator_range<const char*> type;
+};
+
+template<class Formatter>
+struct checked_formatter {
+public:
+ checked_formatter(const Formatter& formatter) : formatter_(formatter) {}
+ template< typename T >
+ typename formatter_result<Formatter>::type operator()( const T & s ) const {
+ BOOST_CHECK( !s.empty() );
+ return formatter_(s);
+ }
+private:
+ Formatter formatter_;
+};
+
+template<class Formatter>
+checked_formatter<Formatter>
+make_checked_formatter(const Formatter& formatter) {
+ return checked_formatter<Formatter>(formatter);
+}
+
 void find_format_test()
 {
     const std::string source = "$replace $replace";
@@ -23,36 +48,53 @@
     std::string output(80, '\0');
 
     std::string::iterator pos =
- boost::find_format_copy(output.begin(),
- source,
- boost::first_finder("$replace"),
- boost::const_formatter("ok"));
+ boost::find_format_copy(
+ output.begin(),
+ source,
+ boost::first_finder("$replace"),
+ make_checked_formatter(boost::const_formatter("ok")));
     BOOST_CHECK(pos == output.begin() + expected.size());
     output.erase(std::remove(output.begin(), output.end(), '\0'), output.end());
     BOOST_CHECK_EQUAL(output, expected);
 
- output = boost::find_format_copy(source, boost::first_finder("$replace"), boost::const_formatter("ok"));
+ output =
+ boost::find_format_copy(
+ source,
+ boost::first_finder("$replace"),
+ make_checked_formatter(boost::const_formatter("ok")));
     BOOST_CHECK_EQUAL(output, expected);
 
     // now try finding a string that doesn't exist
     output.resize(80);
- pos = boost::find_format_copy(output.begin(),
- source,
- boost::first_finder("$noreplace"),
- boost::const_formatter("bad"));
+ pos =
+ boost::find_format_copy(
+ output.begin(),
+ source,
+ boost::first_finder("$noreplace"),
+ make_checked_formatter(boost::const_formatter("bad")));
     BOOST_CHECK(pos == output.begin() + source.size());
     output.erase(std::remove(output.begin(), output.end(), '\0'), output.end());
     BOOST_CHECK_EQUAL(output, source);
 
- output = boost::find_format_copy(source, boost::first_finder("$noreplace"), boost::const_formatter("bad"));
+ output =
+ boost::find_format_copy(
+ source,
+ boost::first_finder("$noreplace"),
+ make_checked_formatter(boost::const_formatter("bad")));
     BOOST_CHECK_EQUAL(output, source);
 
     // in place version
     output = source;
- boost::find_format(output, boost::first_finder("$replace"), boost::const_formatter("ok"));
+ boost::find_format(
+ output,
+ boost::first_finder("$replace"),
+ make_checked_formatter(boost::const_formatter("ok")));
     BOOST_CHECK_EQUAL(output, expected);
     output = source;
- boost::find_format(output, boost::first_finder("$noreplace"), boost::const_formatter("bad"));
+ boost::find_format(
+ output,
+ boost::first_finder("$noreplace"),
+ make_checked_formatter(boost::const_formatter("bad")));
     BOOST_CHECK_EQUAL(output, source);
 }
 
@@ -71,28 +113,44 @@
     output.erase(std::remove(output.begin(), output.end(), '\0'), output.end());
     BOOST_CHECK_EQUAL(output, expected);
 
- output = boost::find_format_all_copy(source, boost::first_finder("$replace"), boost::const_formatter("ok"));
+ output =
+ boost::find_format_all_copy(
+ source,
+ boost::first_finder("$replace"),
+ make_checked_formatter(boost::const_formatter("ok")));
     BOOST_CHECK_EQUAL(output, expected);
 
     // now try finding a string that doesn't exist
     output.resize(80);
- pos = boost::find_format_all_copy(output.begin(),
- source,
- boost::first_finder("$noreplace"),
- boost::const_formatter("bad"));
+ pos =
+ boost::find_format_all_copy(
+ output.begin(),
+ source,
+ boost::first_finder("$noreplace"),
+ make_checked_formatter(boost::const_formatter("bad")));
     BOOST_CHECK(pos == output.begin() + source.size());
     output.erase(std::remove(output.begin(), output.end(), '\0'), output.end());
     BOOST_CHECK_EQUAL(output, source);
 
- output = boost::find_format_all_copy(source, boost::first_finder("$noreplace"), boost::const_formatter("bad"));
+ output =
+ boost::find_format_all_copy(
+ source,
+ boost::first_finder("$noreplace"),
+ make_checked_formatter(boost::const_formatter("bad")));
     BOOST_CHECK_EQUAL(output, source);
 
     // in place version
     output = source;
- boost::find_format_all(output, boost::first_finder("$replace"), boost::const_formatter("ok"));
+ boost::find_format_all(
+ output,
+ boost::first_finder("$replace"),
+ make_checked_formatter(boost::const_formatter("ok")));
     BOOST_CHECK_EQUAL(output, expected);
     output = source;
- boost::find_format_all(output, boost::first_finder("$noreplace"), boost::const_formatter("bad"));
+ boost::find_format_all(
+ output,
+ boost::first_finder("$noreplace"),
+ make_checked_formatter(boost::const_formatter("bad")));
     BOOST_CHECK_EQUAL(output, source);
 }
 


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