Avoid calling the formatter with an invalid match. Fixes #2777

[SVN r62695]
This commit is contained in:
Steven Watanabe
2010-06-09 23:04:24 +00:00
parent 46ed1bf987
commit 672775545d
4 changed files with 147 additions and 58 deletions

View File

@ -74,13 +74,17 @@ namespace boost {
const InputT& Input, const InputT& Input,
FormatterT Formatter, FormatterT Formatter,
const FindResultT& FindResult ) const FindResultT& FindResult )
{ {
return ::boost::algorithm::detail::find_format_copy_impl2( if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) {
Output, return ::boost::algorithm::detail::find_format_copy_impl2(
Input, Output,
Formatter, Input,
FindResult, Formatter,
Formatter(FindResult) ); FindResult,
Formatter(FindResult) );
} else {
return std::copy( ::boost::begin(Input), ::boost::end(Input), Output );
}
} }
@ -132,11 +136,15 @@ namespace boost {
FormatterT Formatter, FormatterT Formatter,
const FindResultT& FindResult) const FindResultT& FindResult)
{ {
return ::boost::algorithm::detail::find_format_copy_impl2( if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) {
Input, return ::boost::algorithm::detail::find_format_copy_impl2(
Formatter, Input,
FindResult, Formatter,
Formatter(FindResult) ); FindResult,
Formatter(FindResult) );
} else {
return Input;
}
} }
// replace implementation ----------------------------------------------------// // replace implementation ----------------------------------------------------//
@ -180,11 +188,13 @@ namespace boost {
FormatterT Formatter, FormatterT Formatter,
const FindResultT& FindResult) const FindResultT& FindResult)
{ {
::boost::algorithm::detail::find_format_impl2( if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) {
Input, ::boost::algorithm::detail::find_format_impl2(
Formatter, Input,
FindResult, Formatter,
Formatter(FindResult) ); FindResult,
Formatter(FindResult) );
}
} }
} // namespace detail } // namespace detail

View File

@ -84,14 +84,18 @@ namespace boost {
FinderT Finder, FinderT Finder,
FormatterT Formatter, FormatterT Formatter,
const FindResultT& FindResult ) const FindResultT& FindResult )
{ {
return ::boost::algorithm::detail::find_format_all_copy_impl2( if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) {
Output, return ::boost::algorithm::detail::find_format_all_copy_impl2(
Input, Output,
Finder, Input,
Formatter, Finder,
FindResult, Formatter,
Formatter(FindResult) ); FindResult,
Formatter(FindResult) );
} else {
return std::copy( ::boost::begin(Input), ::boost::end(Input), Output );
}
} }
// find_format_all_copy implementation ----------------------------------------------// // find_format_all_copy implementation ----------------------------------------------//
@ -156,12 +160,16 @@ namespace boost {
FormatterT Formatter, FormatterT Formatter,
const FindResultT& FindResult) const FindResultT& FindResult)
{ {
return ::boost::algorithm::detail::find_format_all_copy_impl2( if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) {
Input, return ::boost::algorithm::detail::find_format_all_copy_impl2(
Finder, Input,
Formatter, Finder,
FindResult, Formatter,
Formatter(FindResult) ); FindResult,
Formatter(FindResult) );
} else {
return Input;
}
} }
// find_format_all implementation ------------------------------------------------// // find_format_all implementation ------------------------------------------------//
@ -248,12 +256,14 @@ namespace boost {
FormatterT Formatter, FormatterT Formatter,
FindResultT FindResult) FindResultT FindResult)
{ {
::boost::algorithm::detail::find_format_all_impl2( if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) {
Input, ::boost::algorithm::detail::find_format_all_impl2(
Finder, Input,
Formatter, Finder,
FindResult, Formatter,
Formatter(FindResult) ); FindResult,
Formatter(FindResult) );
}
} }
} // namespace detail } // namespace detail

View File

@ -52,7 +52,9 @@ namespace boost {
find_format_store& operator=( FindResultT FindResult ) find_format_store& operator=( FindResultT FindResult )
{ {
iterator_range<ForwardIteratorT>::operator=(FindResult); iterator_range<ForwardIteratorT>::operator=(FindResult);
m_FormatResult=m_Formatter(FindResult); if( !this->empty() ) {
m_FormatResult=m_Formatter(FindResult);
}
return *this; return *this;
} }
@ -68,6 +70,15 @@ namespace boost {
const formatter_type& m_Formatter; 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) #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
#pragma warning(pop) #pragma warning(pop)
#endif #endif

View File

@ -16,6 +16,31 @@
#include <boost/test/test_tools.hpp> #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() void find_format_test()
{ {
const std::string source = "$replace $replace"; const std::string source = "$replace $replace";
@ -23,36 +48,53 @@ void find_format_test()
std::string output(80, '\0'); std::string output(80, '\0');
std::string::iterator pos = std::string::iterator pos =
boost::find_format_copy(output.begin(), boost::find_format_copy(
source, output.begin(),
boost::first_finder("$replace"), source,
boost::const_formatter("ok")); boost::first_finder("$replace"),
make_checked_formatter(boost::const_formatter("ok")));
BOOST_CHECK(pos == output.begin() + expected.size()); BOOST_CHECK(pos == output.begin() + expected.size());
output.erase(std::remove(output.begin(), output.end(), '\0'), output.end()); output.erase(std::remove(output.begin(), output.end(), '\0'), output.end());
BOOST_CHECK_EQUAL(output, expected); 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); BOOST_CHECK_EQUAL(output, expected);
// now try finding a string that doesn't exist // now try finding a string that doesn't exist
output.resize(80); output.resize(80);
pos = boost::find_format_copy(output.begin(), pos =
source, boost::find_format_copy(
boost::first_finder("$noreplace"), output.begin(),
boost::const_formatter("bad")); source,
boost::first_finder("$noreplace"),
make_checked_formatter(boost::const_formatter("bad")));
BOOST_CHECK(pos == output.begin() + source.size()); BOOST_CHECK(pos == output.begin() + source.size());
output.erase(std::remove(output.begin(), output.end(), '\0'), output.end()); output.erase(std::remove(output.begin(), output.end(), '\0'), output.end());
BOOST_CHECK_EQUAL(output, source); 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); BOOST_CHECK_EQUAL(output, source);
// in place version // in place version
output = source; 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); BOOST_CHECK_EQUAL(output, expected);
output = source; 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); BOOST_CHECK_EQUAL(output, source);
} }
@ -71,28 +113,44 @@ void find_format_all_test()
output.erase(std::remove(output.begin(), output.end(), '\0'), output.end()); output.erase(std::remove(output.begin(), output.end(), '\0'), output.end());
BOOST_CHECK_EQUAL(output, expected); 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); BOOST_CHECK_EQUAL(output, expected);
// now try finding a string that doesn't exist // now try finding a string that doesn't exist
output.resize(80); output.resize(80);
pos = boost::find_format_all_copy(output.begin(), pos =
source, boost::find_format_all_copy(
boost::first_finder("$noreplace"), output.begin(),
boost::const_formatter("bad")); source,
boost::first_finder("$noreplace"),
make_checked_formatter(boost::const_formatter("bad")));
BOOST_CHECK(pos == output.begin() + source.size()); BOOST_CHECK(pos == output.begin() + source.size());
output.erase(std::remove(output.begin(), output.end(), '\0'), output.end()); output.erase(std::remove(output.begin(), output.end(), '\0'), output.end());
BOOST_CHECK_EQUAL(output, source); 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); BOOST_CHECK_EQUAL(output, source);
// in place version // in place version
output = source; 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); BOOST_CHECK_EQUAL(output, expected);
output = source; 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_CHECK_EQUAL(output, source);
} }