mirror of
https://github.com/catchorg/Catch2.git
synced 2024-11-30 01:03:30 +01:00
StringRef no longer repoints m_start to m_data after c_str() on a substring.
This fixes an issue where a self-assignment of a StringRef copy would point into internally (and now dangling) data. (now self-assignment check is no longer needed)
This commit is contained in:
parent
71fce429af
commit
96355da34e
@ -39,9 +39,11 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto StringRef::c_str() const -> char const* {
|
auto StringRef::c_str() const -> char const* {
|
||||||
if( isSubstring() )
|
if( !isSubstring() )
|
||||||
const_cast<StringRef*>( this )->takeOwnership();
|
|
||||||
return m_start;
|
return m_start;
|
||||||
|
|
||||||
|
const_cast<StringRef *>( this )->takeOwnership();
|
||||||
|
return m_data;
|
||||||
}
|
}
|
||||||
auto StringRef::currentData() const noexcept -> char const* {
|
auto StringRef::currentData() const noexcept -> char const* {
|
||||||
return m_start;
|
return m_start;
|
||||||
@ -59,7 +61,6 @@ namespace Catch {
|
|||||||
m_data = new char[m_size+1];
|
m_data = new char[m_size+1];
|
||||||
memcpy( m_data, m_start, m_size );
|
memcpy( m_data, m_start, m_size );
|
||||||
m_data[m_size] = '\0';
|
m_data[m_size] = '\0';
|
||||||
m_start = m_data;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto StringRef::substr( size_type start, size_type size ) const noexcept -> StringRef {
|
auto StringRef::substr( size_type start, size_type size ) const noexcept -> StringRef {
|
||||||
|
@ -71,12 +71,12 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto operator = ( StringRef const &other ) noexcept -> StringRef& {
|
auto operator = ( StringRef const &other ) noexcept -> StringRef& {
|
||||||
if( this != &other ) {
|
// if( this != &other ) {
|
||||||
delete[] m_data;
|
delete[] m_data;
|
||||||
m_data = nullptr;
|
m_data = nullptr;
|
||||||
m_start = other.m_start;
|
m_start = other.m_start;
|
||||||
m_size = other.m_size;
|
m_size = other.m_size;
|
||||||
}
|
// }
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,7 +65,6 @@ TEST_CASE( "StringRef", "[Strings][StringRef]" ) {
|
|||||||
|
|
||||||
original.c_str(); // Forces it to take ownership
|
original.c_str(); // Forces it to take ownership
|
||||||
|
|
||||||
REQUIRE( isSubstring( original ) == false );
|
|
||||||
REQUIRE( isOwned( original ) );
|
REQUIRE( isOwned( original ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,14 +87,13 @@ TEST_CASE( "StringRef", "[Strings][StringRef]" ) {
|
|||||||
REQUIRE( rawChars == s.currentData() ); // same pointer value
|
REQUIRE( rawChars == s.currentData() ); // same pointer value
|
||||||
REQUIRE( ss.c_str() != rawChars );
|
REQUIRE( ss.c_str() != rawChars );
|
||||||
|
|
||||||
REQUIRE( isSubstring( ss ) == false );
|
|
||||||
REQUIRE( isOwned( ss ) );
|
REQUIRE( isOwned( ss ) );
|
||||||
|
|
||||||
REQUIRE( ss.currentData() != s.currentData() ); // different pointer value
|
|
||||||
|
|
||||||
SECTION( "Self-assignment after substring" ) {
|
SECTION( "Self-assignment after substring" ) {
|
||||||
ss = *&ss; // the *& are there to suppress warnings (see: "Improvements to Clang's diagnostics" in https://rev.ng/gitlab/revng-bar-2019/clang/raw/master/docs/ReleaseNotes.rst)
|
ss = *&ss; // the *& are there to suppress warnings (see: "Improvements to Clang's diagnostics" in https://rev.ng/gitlab/revng-bar-2019/clang/raw/master/docs/ReleaseNotes.rst)
|
||||||
REQUIRE(isOwned(ss) == true);
|
REQUIRE( isOwned(ss) == false );
|
||||||
|
REQUIRE( ss == "hello" );
|
||||||
|
REQUIRE( rawChars == ss.currentData() ); // same pointer value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user