mirror of
https://github.com/boostorg/algorithm.git
synced 2025-07-06 09:16:33 +02:00
Avoid calling the formatter with an invalid match. Fixes #2777
[SVN r62695]
This commit is contained in:
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user