PR #21321 talked about implementation-defined behavior of realloc. I poo-poohed it, and was wrong. Fix the call in <locale>. Review the others, refactored some duplicated code, and found overflow bugs (and __event_cap_ was never getting updated, either).
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@220702 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
129e07fe99
commit
1d306de1a7
@ -2970,6 +2970,8 @@ __double_or_nothing(unique_ptr<_Tp, void(*)(void*)>& __b, _Tp*& __n, _Tp*& __e)
|
|||||||
size_t __cur_cap = static_cast<size_t>(__e-__b.get()) * sizeof(_Tp);
|
size_t __cur_cap = static_cast<size_t>(__e-__b.get()) * sizeof(_Tp);
|
||||||
size_t __new_cap = __cur_cap < numeric_limits<size_t>::max() / 2 ?
|
size_t __new_cap = __cur_cap < numeric_limits<size_t>::max() / 2 ?
|
||||||
2 * __cur_cap : numeric_limits<size_t>::max();
|
2 * __cur_cap : numeric_limits<size_t>::max();
|
||||||
|
if (__new_cap == 0)
|
||||||
|
__new_cap = sizeof(_Tp);
|
||||||
size_t __n_off = static_cast<size_t>(__n - __b.get());
|
size_t __n_off = static_cast<size_t>(__n - __b.get());
|
||||||
_Tp* __t = (_Tp*)realloc(__owns ? __b.get() : 0, __new_cap);
|
_Tp* __t = (_Tp*)realloc(__owns ? __b.get() : 0, __new_cap);
|
||||||
if (__t == 0)
|
if (__t == 0)
|
||||||
|
50
src/ios.cpp
50
src/ios.cpp
@ -154,6 +154,16 @@ atomic<int> ios_base::__xindex_ = ATOMIC_VAR_INIT(0);
|
|||||||
int ios_base::__xindex_ = 0;
|
int ios_base::__xindex_ = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
template <typename _Tp>
|
||||||
|
static size_t __ios_new_cap(size_t __req_size, size_t __current_cap)
|
||||||
|
{ // Precondition: __req_size > __current_cap
|
||||||
|
const size_t mx = std::numeric_limits<size_t>::max() / sizeof(_Tp);
|
||||||
|
if (__req_size < mx/2)
|
||||||
|
return _VSTD::max(2 * __current_cap, __req_size);
|
||||||
|
else
|
||||||
|
return mx;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ios_base::xalloc()
|
ios_base::xalloc()
|
||||||
{
|
{
|
||||||
@ -166,14 +176,8 @@ ios_base::iword(int index)
|
|||||||
size_t req_size = static_cast<size_t>(index)+1;
|
size_t req_size = static_cast<size_t>(index)+1;
|
||||||
if (req_size > __iarray_cap_)
|
if (req_size > __iarray_cap_)
|
||||||
{
|
{
|
||||||
size_t newcap;
|
size_t newcap = __ios_new_cap<long>(req_size, __iarray_cap_);
|
||||||
const size_t mx = std::numeric_limits<size_t>::max();
|
long* iarray = static_cast<long*>(realloc(__iarray_, newcap * sizeof(long)));
|
||||||
if (req_size < mx/2)
|
|
||||||
newcap = _VSTD::max(2 * __iarray_cap_, req_size);
|
|
||||||
else
|
|
||||||
newcap = mx;
|
|
||||||
size_t newsize = newcap * sizeof(long);
|
|
||||||
long* iarray = static_cast<long*>(realloc(__iarray_, newsize));
|
|
||||||
if (iarray == 0)
|
if (iarray == 0)
|
||||||
{
|
{
|
||||||
setstate(badbit);
|
setstate(badbit);
|
||||||
@ -182,8 +186,9 @@ ios_base::iword(int index)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
__iarray_ = iarray;
|
__iarray_ = iarray;
|
||||||
for (long* p = __iarray_ + __iarray_size_; __iarray_cap_ < newcap; ++__iarray_cap_, ++p)
|
for (long* p = __iarray_ + __iarray_size_; p < __iarray_ + newcap; ++p)
|
||||||
*p = 0;
|
*p = 0;
|
||||||
|
__iarray_cap_ = newcap;
|
||||||
}
|
}
|
||||||
__iarray_size_ = max<size_t>(__iarray_size_, req_size);
|
__iarray_size_ = max<size_t>(__iarray_size_, req_size);
|
||||||
return __iarray_[index];
|
return __iarray_[index];
|
||||||
@ -195,14 +200,8 @@ ios_base::pword(int index)
|
|||||||
size_t req_size = static_cast<size_t>(index)+1;
|
size_t req_size = static_cast<size_t>(index)+1;
|
||||||
if (req_size > __parray_cap_)
|
if (req_size > __parray_cap_)
|
||||||
{
|
{
|
||||||
size_t newcap;
|
size_t newcap = __ios_new_cap<void *>(req_size, __iarray_cap_);
|
||||||
const size_t mx = std::numeric_limits<size_t>::max();
|
void** parray = static_cast<void**>(realloc(__parray_, newcap * sizeof(void *)));
|
||||||
if (req_size < mx/2)
|
|
||||||
newcap = _VSTD::max(2 * __parray_cap_, req_size);
|
|
||||||
else
|
|
||||||
newcap = mx;
|
|
||||||
size_t newsize = newcap * sizeof(void*);
|
|
||||||
void** parray = static_cast<void**>(realloc(__parray_, newsize));
|
|
||||||
if (parray == 0)
|
if (parray == 0)
|
||||||
{
|
{
|
||||||
setstate(badbit);
|
setstate(badbit);
|
||||||
@ -211,8 +210,9 @@ ios_base::pword(int index)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
__parray_ = parray;
|
__parray_ = parray;
|
||||||
for (void** p = __parray_ + __parray_size_; __parray_cap_ < newcap; ++__parray_cap_, ++p)
|
for (void** p = __parray_ + __parray_size_; p < __parray_ + newcap; ++p)
|
||||||
*p = 0;
|
*p = 0;
|
||||||
|
__parray_cap_ = newcap;
|
||||||
}
|
}
|
||||||
__parray_size_ = max<size_t>(__parray_size_, req_size);
|
__parray_size_ = max<size_t>(__parray_size_, req_size);
|
||||||
return __parray_[index];
|
return __parray_[index];
|
||||||
@ -226,22 +226,16 @@ ios_base::register_callback(event_callback fn, int index)
|
|||||||
size_t req_size = __event_size_ + 1;
|
size_t req_size = __event_size_ + 1;
|
||||||
if (req_size > __event_cap_)
|
if (req_size > __event_cap_)
|
||||||
{
|
{
|
||||||
size_t newcap;
|
size_t newcap = __ios_new_cap<event_callback>(req_size, __event_cap_);
|
||||||
const size_t mx = std::numeric_limits<size_t>::max();
|
event_callback* fns = static_cast<event_callback*>(realloc(__fn_, newcap * sizeof(event_callback)));
|
||||||
if (req_size < mx/2)
|
|
||||||
newcap = _VSTD::max(2 * __event_cap_, req_size);
|
|
||||||
else
|
|
||||||
newcap = mx;
|
|
||||||
size_t newesize = newcap * sizeof(event_callback);
|
|
||||||
event_callback* fns = static_cast<event_callback*>(realloc(__fn_, newesize));
|
|
||||||
if (fns == 0)
|
if (fns == 0)
|
||||||
setstate(badbit);
|
setstate(badbit);
|
||||||
__fn_ = fns;
|
__fn_ = fns;
|
||||||
size_t newisize = newcap * sizeof(int);
|
int* indxs = static_cast<int *>(realloc(__index_, newcap * sizeof(int)));
|
||||||
int* indxs = static_cast<int *>(realloc(__index_, newisize));
|
|
||||||
if (indxs == 0)
|
if (indxs == 0)
|
||||||
setstate(badbit);
|
setstate(badbit);
|
||||||
__index_ = indxs;
|
__index_ = indxs;
|
||||||
|
__event_cap_ = newcap;
|
||||||
}
|
}
|
||||||
__fn_[__event_size_] = fn;
|
__fn_[__event_size_] = fn;
|
||||||
__index_[__event_size_] = index;
|
__index_[__event_size_] = index;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user