From 9c1540ffe31f6cad02ebda4a1cfb49ed50454a1e Mon Sep 17 00:00:00 2001 From: Alexander Lauser Date: Sun, 18 Oct 2015 18:58:46 +0200 Subject: [PATCH] Fixed Ticket #9518. Added test detecting that Bug. --- include/boost/utility/string_ref.hpp | 14 +++++++------- test/string_ref_test2.cpp | 26 +++++++++++++++++++++++--- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/include/boost/utility/string_ref.hpp b/include/boost/utility/string_ref.hpp index 8707157c6..3dc286a55 100644 --- a/include/boost/utility/string_ref.hpp +++ b/include/boost/utility/string_ref.hpp @@ -174,13 +174,13 @@ namespace boost { size_type rfind(basic_string_ref s) const { const_reverse_iterator iter = std::search ( this->crbegin (), this->crend (), s.crbegin (), s.crend (), traits::eq ); - return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter ); + return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter, s.length() ); } size_type rfind(charT c) const { const_reverse_iterator iter = std::find_if ( this->crbegin (), this->crend (), detail::string_ref_traits_eq ( c )); - return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter ); + return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter, 1 ); } size_type find_first_of(charT c) const { return find (c); } @@ -195,7 +195,7 @@ namespace boost { size_type find_last_of(basic_string_ref s) const { const_reverse_iterator iter = std::find_first_of ( this->crbegin (), this->crend (), s.cbegin (), s.cend (), traits::eq ); - return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter); + return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter, 1 ); } size_type find_first_not_of(basic_string_ref s) const { @@ -212,20 +212,20 @@ namespace boost { size_type find_last_not_of(basic_string_ref s) const { const_reverse_iterator iter = find_not_of ( this->crbegin (), this->crend (), s ); - return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter ); + return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter, 1 ); } size_type find_last_not_of(charT c) const { for ( const_reverse_iterator iter = this->crbegin (); iter != this->crend (); ++iter ) if ( !traits::eq ( c, *iter )) - return reverse_distance ( this->crbegin (), iter ); + return reverse_distance ( this->crbegin (), iter, 1 ); return npos; } private: template - size_type reverse_distance ( r_iter first, r_iter last ) const { - return len_ - 1 - std::distance ( first, last ); + size_type reverse_distance ( r_iter first, r_iter last, size_type correction ) const { + return len_ - correction - std::distance ( first, last ); } template diff --git a/test/string_ref_test2.cpp b/test/string_ref_test2.cpp index 9559c6712..037564b17 100644 --- a/test/string_ref_test2.cpp +++ b/test/string_ref_test2.cpp @@ -90,35 +90,55 @@ string_ref::size_type ptr_diff ( const char *res, const char *base ) { } void find ( const char *arg ) { + std::string stdstr1; string_ref sr1; string_ref sr2; const char *p; -// Look for each character in the string(searching from the start) +// Look for each character in the string(searching from the start) and compare outcome to that of std::string p = arg; sr1 = arg; + stdstr1 = arg; while ( *p ) { string_ref::size_type pos = sr1.find(*p); BOOST_CHECK ( pos != string_ref::npos && ( pos <= ptr_diff ( p, arg ))); + BOOST_CHECK_EQUAL ( pos , stdstr1.find(*p) ); ++p; } -// Look for each character in the string (searching from the end) +// Look for each character in the string (searching from the end) and compare outcome to that of std::string p = arg; sr1 = arg; + stdstr1 = arg; while ( *p ) { string_ref::size_type pos = sr1.rfind(*p); BOOST_CHECK ( pos != string_ref::npos && pos < sr1.size () && ( pos >= ptr_diff ( p, arg ))); + BOOST_CHECK_EQUAL ( pos , stdstr1.rfind(*p) ); ++p; } -// Look for pairs on characters (searching from the start) +// Look for pairs on characters (searching from the start) and compare outcome to that of std::string sr1 = arg; + stdstr1 = arg; p = arg; while ( *p && *(p+1)) { string_ref sr3 ( p, 2 ); string_ref::size_type pos = sr1.find ( sr3 ); BOOST_CHECK ( pos != string_ref::npos && pos <= static_cast( p - arg )); + BOOST_CHECK_EQUAL ( pos , stdstr1.find(sr3.to_string()) ); + p++; + } + +// Look for pairs on characters (searching from the end) and compare outcomes to that of std::string +// This test detects Bug #9518 + sr1 = arg; + stdstr1 = arg; + p = arg; + while ( *p && *(p+1)) { + string_ref sr3 ( p, 2 ); + string_ref::size_type pos = sr1.rfind ( sr3 ); + BOOST_CHECK ( pos != string_ref::npos && pos >= static_cast( p - arg )); + BOOST_CHECK_EQUAL ( pos , stdstr1.rfind(sr3.to_string()) ); p++; }