libstdc++: Fix null pointer dereferences in __gnu_cxx::rope
This fixes UBsan errors like: /usr/include/c++/10/ext/ropeimpl.h:593:9: runtime error: member access within null pointer of type 'struct _RopeRep' /usr/include/c++/10/ext/ropeimpl.h:593:9: runtime error: member call on null pointer of type 'struct _Rope_rep_base' /usr/include/c++/10/ext/rope:556:17: runtime error: reference binding to null pointer of type 'struct allocator_type' /usr/include/c++/10/ext/ropeimpl.h:593:9: runtime error: reference binding to null pointer of type 'struct allocator_type' /usr/include/c++/10/ext/rope:1700:30: runtime error: member call on null pointer of type 'struct new_allocator' /usr/include/c++/10/ext/new_allocator.h:105:29: runtime error: member call on null pointer of type 'struct new_allocator' /usr/include/c++/10/ext/rope:1702:26: runtime error: reference binding to null pointer of type 'const struct allocator' /usr/include/c++/10/bits/allocator.h:148:34: runtime error: reference binding to null pointer of type 'const struct new_allocator' /usr/include/c++/10/ext/rope:1664:39: runtime error: reference binding to null pointer of type 'const struct allocator' /usr/include/c++/10/ext/rope:1665:9: runtime error: reference binding to null pointer of type 'const struct allocator_type' /usr/include/c++/10/ext/rope:725:36: runtime error: reference binding to null pointer of type 'const struct allocator_type' /usr/include/c++/10/ext/rope:614:64: runtime error: reference binding to null pointer of type 'const struct allocator_type' The problem is calling r->_M_get_allocator() when r is null. libstdc++-v3/ChangeLog: * include/ext/rope (rope::_S_concat_char_iter) (rope::_S_destr_concat_char_iter): Add allocator parameter. (rope::push_back, rope::append, rope::insert, operator+): Pass allocator. * include/ext/ropeimpl.h (rope::_S_concat_char_iter) (rope::_S_destr_concat_char_iter): Add allocator parameter and use it. (_Rope_char_ref_proxy::operator=(_CharT)): Pass allocator.
This commit is contained in:
parent
d38fbb5a86
commit
74270a546c
@ -1612,19 +1612,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
|
|
||||||
static _RopeRep* _S_concat_char_iter(_RopeRep* __r,
|
static _RopeRep* _S_concat_char_iter(_RopeRep* __r,
|
||||||
const _CharT* __iter,
|
const _CharT* __iter,
|
||||||
size_type __slen);
|
size_type __slen,
|
||||||
// Concatenate rope and char ptr, copying __s.
|
allocator_type& __a);
|
||||||
|
// Concatenate rope and char ptr, copying __iter.
|
||||||
// Should really take an arbitrary iterator.
|
// Should really take an arbitrary iterator.
|
||||||
// Result is counted in refcount.
|
// Result is counted in refcount.
|
||||||
static _RopeRep* _S_destr_concat_char_iter(_RopeRep* __r,
|
static _RopeRep* _S_destr_concat_char_iter(_RopeRep* __r,
|
||||||
const _CharT* __iter,
|
const _CharT* __iter,
|
||||||
size_type __slen)
|
size_type __slen,
|
||||||
|
allocator_type& __a)
|
||||||
// As above, but one reference to __r is about to be
|
// As above, but one reference to __r is about to be
|
||||||
// destroyed. Thus the pieces may be recycled if all
|
// destroyed. Thus the pieces may be recycled if all
|
||||||
// relevant reference counts are 1.
|
// relevant reference counts are 1.
|
||||||
#ifdef __GC
|
#ifdef __GC
|
||||||
// We can't really do anything since refcounts are unavailable.
|
// We can't really do anything since refcounts are unavailable.
|
||||||
{ return _S_concat_char_iter(__r, __iter, __slen); }
|
{ return _S_concat_char_iter(__r, __iter, __slen, __a); }
|
||||||
#else
|
#else
|
||||||
;
|
;
|
||||||
#endif
|
#endif
|
||||||
@ -1913,9 +1915,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
void
|
void
|
||||||
push_back(_CharT __x)
|
push_back(_CharT __x)
|
||||||
{
|
{
|
||||||
|
allocator_type __a = _M_get_allocator();
|
||||||
_RopeRep* __old = this->_M_tree_ptr;
|
_RopeRep* __old = this->_M_tree_ptr;
|
||||||
this->_M_tree_ptr
|
this->_M_tree_ptr
|
||||||
= _S_destr_concat_char_iter(this->_M_tree_ptr, &__x, 1);
|
= _S_destr_concat_char_iter(this->_M_tree_ptr, &__x, 1, __a);
|
||||||
_S_unref(__old);
|
_S_unref(__old);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2115,8 +2118,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
rope&
|
rope&
|
||||||
append(const _CharT* __iter, size_type __n)
|
append(const _CharT* __iter, size_type __n)
|
||||||
{
|
{
|
||||||
|
allocator_type __a = _M_get_allocator();
|
||||||
_RopeRep* __result =
|
_RopeRep* __result =
|
||||||
_S_destr_concat_char_iter(this->_M_tree_ptr, __iter, __n);
|
_S_destr_concat_char_iter(this->_M_tree_ptr, __iter, __n, __a);
|
||||||
_S_unref(this->_M_tree_ptr);
|
_S_unref(this->_M_tree_ptr);
|
||||||
this->_M_tree_ptr = __result;
|
this->_M_tree_ptr = __result;
|
||||||
return *this;
|
return *this;
|
||||||
@ -2133,8 +2137,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
rope&
|
rope&
|
||||||
append(const _CharT* __s, const _CharT* __e)
|
append(const _CharT* __s, const _CharT* __e)
|
||||||
{
|
{
|
||||||
|
allocator_type __a = _M_get_allocator();
|
||||||
_RopeRep* __result =
|
_RopeRep* __result =
|
||||||
_S_destr_concat_char_iter(this->_M_tree_ptr, __s, __e - __s);
|
_S_destr_concat_char_iter(this->_M_tree_ptr, __s, __e - __s, __a);
|
||||||
_S_unref(this->_M_tree_ptr);
|
_S_unref(this->_M_tree_ptr);
|
||||||
this->_M_tree_ptr = __result;
|
this->_M_tree_ptr = __result;
|
||||||
return *this;
|
return *this;
|
||||||
@ -2156,8 +2161,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
rope&
|
rope&
|
||||||
append(_CharT __c)
|
append(_CharT __c)
|
||||||
{
|
{
|
||||||
|
allocator_type __a = _M_get_allocator();
|
||||||
_RopeRep* __result =
|
_RopeRep* __result =
|
||||||
_S_destr_concat_char_iter(this->_M_tree_ptr, &__c, 1);
|
_S_destr_concat_char_iter(this->_M_tree_ptr, &__c, 1, __a);
|
||||||
_S_unref(this->_M_tree_ptr);
|
_S_unref(this->_M_tree_ptr);
|
||||||
this->_M_tree_ptr = __result;
|
this->_M_tree_ptr = __result;
|
||||||
return *this;
|
return *this;
|
||||||
@ -2239,7 +2245,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
_Self_destruct_ptr __left(_S_substring(this->_M_tree_ptr, 0, __p));
|
_Self_destruct_ptr __left(_S_substring(this->_M_tree_ptr, 0, __p));
|
||||||
_Self_destruct_ptr __right(_S_substring(this->_M_tree_ptr,
|
_Self_destruct_ptr __right(_S_substring(this->_M_tree_ptr,
|
||||||
__p, size()));
|
__p, size()));
|
||||||
_Self_destruct_ptr __left_result(_S_concat_char_iter(__left, __i, __n));
|
_Self_destruct_ptr __left_result(_S_concat_char_iter(__left, __i, __n,
|
||||||
|
_M_get_allocator()));
|
||||||
// _S_ destr_concat_char_iter should be safe here.
|
// _S_ destr_concat_char_iter should be safe here.
|
||||||
// But as it stands it's probably not a win, since __left
|
// But as it stands it's probably not a win, since __left
|
||||||
// is likely to have additional references.
|
// is likely to have additional references.
|
||||||
@ -2843,8 +2850,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
{
|
{
|
||||||
typedef rope<_CharT, _Alloc> rope_type;
|
typedef rope<_CharT, _Alloc> rope_type;
|
||||||
std::size_t __rlen = rope_type::_S_char_ptr_len(__right);
|
std::size_t __rlen = rope_type::_S_char_ptr_len(__right);
|
||||||
|
_Alloc __a = __left.get_allocator();
|
||||||
return rope_type(rope_type::_S_concat_char_iter(__left._M_tree_ptr,
|
return rope_type(rope_type::_S_concat_char_iter(__left._M_tree_ptr,
|
||||||
__right, __rlen));
|
__right, __rlen, __a));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _CharT, class _Alloc>
|
template <class _CharT, class _Alloc>
|
||||||
@ -2861,8 +2869,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
operator+(const rope<_CharT, _Alloc>& __left, _CharT __right)
|
operator+(const rope<_CharT, _Alloc>& __left, _CharT __right)
|
||||||
{
|
{
|
||||||
typedef rope<_CharT, _Alloc> rope_type;
|
typedef rope<_CharT, _Alloc> rope_type;
|
||||||
|
_Alloc __a = __left.get_allocator();
|
||||||
return rope_type(rope_type::_S_concat_char_iter(__left._M_tree_ptr,
|
return rope_type(rope_type::_S_concat_char_iter(__left._M_tree_ptr,
|
||||||
&__right, 1));
|
&__right, 1, __a));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _CharT, class _Alloc>
|
template <class _CharT, class _Alloc>
|
||||||
|
@ -524,7 +524,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
template <class _CharT, class _Alloc>
|
template <class _CharT, class _Alloc>
|
||||||
typename rope<_CharT, _Alloc>::_RopeRep*
|
typename rope<_CharT, _Alloc>::_RopeRep*
|
||||||
rope<_CharT, _Alloc>::
|
rope<_CharT, _Alloc>::
|
||||||
_S_concat_char_iter(_RopeRep* __r, const _CharT*__s, std::size_t __slen)
|
_S_concat_char_iter(_RopeRep* __r, const _CharT*__s, std::size_t __slen,
|
||||||
|
allocator_type& __a)
|
||||||
{
|
{
|
||||||
using std::size_t;
|
using std::size_t;
|
||||||
_RopeRep* __result;
|
_RopeRep* __result;
|
||||||
@ -534,8 +535,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
return __r;
|
return __r;
|
||||||
}
|
}
|
||||||
if (0 == __r)
|
if (0 == __r)
|
||||||
return __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen,
|
return __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __a);
|
||||||
__r->_M_get_allocator());
|
|
||||||
if (__r->_M_tag == __detail::_S_leaf
|
if (__r->_M_tag == __detail::_S_leaf
|
||||||
&& __r->_M_size + __slen <= size_t(_S_copy_max))
|
&& __r->_M_size + __slen <= size_t(_S_copy_max))
|
||||||
{
|
{
|
||||||
@ -564,8 +564,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
return __result;
|
return __result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_RopeRep* __nright =
|
_RopeRep* __nright = __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __a);
|
||||||
__STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __r->_M_get_allocator());
|
|
||||||
__try
|
__try
|
||||||
{
|
{
|
||||||
__r->_M_ref_nonnil();
|
__r->_M_ref_nonnil();
|
||||||
@ -585,17 +584,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
typename rope<_CharT,_Alloc>::_RopeRep*
|
typename rope<_CharT,_Alloc>::_RopeRep*
|
||||||
rope<_CharT,_Alloc>::
|
rope<_CharT,_Alloc>::
|
||||||
_S_destr_concat_char_iter(_RopeRep* __r, const _CharT* __s,
|
_S_destr_concat_char_iter(_RopeRep* __r, const _CharT* __s,
|
||||||
std::size_t __slen)
|
std::size_t __slen, allocator_type& __a)
|
||||||
{
|
{
|
||||||
using std::size_t;
|
using std::size_t;
|
||||||
_RopeRep* __result;
|
_RopeRep* __result;
|
||||||
if (0 == __r)
|
if (0 == __r)
|
||||||
return __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen,
|
return __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __a);
|
||||||
__r->_M_get_allocator());
|
|
||||||
size_t __count = __r->_M_ref_count;
|
size_t __count = __r->_M_ref_count;
|
||||||
size_t __orig_size = __r->_M_size;
|
size_t __orig_size = __r->_M_size;
|
||||||
if (__count > 1)
|
if (__count > 1)
|
||||||
return _S_concat_char_iter(__r, __s, __slen);
|
return _S_concat_char_iter(__r, __s, __slen, __a);
|
||||||
if (0 == __slen)
|
if (0 == __slen)
|
||||||
{
|
{
|
||||||
__r->_M_ref_count = 2; // One more than before
|
__r->_M_ref_count = 2; // One more than before
|
||||||
@ -632,8 +630,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
return __r;
|
return __r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_RopeRep* __right =
|
_RopeRep* __right = __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __a);
|
||||||
__STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __r->_M_get_allocator());
|
|
||||||
__r->_M_ref_nonnil();
|
__r->_M_ref_nonnil();
|
||||||
__try
|
__try
|
||||||
{ __result = _S_tree_concat(__r, __right); }
|
{ __result = _S_tree_concat(__r, __right); }
|
||||||
@ -1500,9 +1497,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
_Self_destruct_ptr __left(_My_rope::_S_substring(__old, 0, _M_pos));
|
_Self_destruct_ptr __left(_My_rope::_S_substring(__old, 0, _M_pos));
|
||||||
_Self_destruct_ptr __right(_My_rope::_S_substring(__old, _M_pos + 1,
|
_Self_destruct_ptr __right(_My_rope::_S_substring(__old, _M_pos + 1,
|
||||||
__old->_M_size));
|
__old->_M_size));
|
||||||
|
typename _RopeRep::allocator_type __a = _M_root->_M_get_allocator();
|
||||||
_Self_destruct_ptr __result_left(_My_rope::
|
_Self_destruct_ptr __result_left(_My_rope::
|
||||||
_S_destr_concat_char_iter(__left,
|
_S_destr_concat_char_iter(__left,
|
||||||
&__c, 1));
|
&__c, 1,
|
||||||
|
__a));
|
||||||
|
|
||||||
_RopeRep* __result = _My_rope::_S_concat(__result_left, __right);
|
_RopeRep* __result = _My_rope::_S_concat(__result_left, __right);
|
||||||
#ifndef __GC
|
#ifndef __GC
|
||||||
|
Loading…
Reference in New Issue
Block a user