forked from OSchip/llvm-project
libcxx: Fix for basic_stringbuf::seekoff() after r320604.
As a result of this change, the basic_stringbuf constructor that takes a mode ends up leaving __hm_ set to 0, causing the comparison "__hm_ - __str_.data() < __noff" in seekoff() to succeed, which caused the function to incorrectly return -1. The fix is to account for the possibility of __hm_ being 0 when computing the distance from __hm_ to the start of the string. Differential Revision: https://reviews.llvm.org/D41319 llvm-svn: 321124
This commit is contained in:
parent
7e13aef428
commit
22c651c577
|
@ -577,6 +577,7 @@ basic_stringbuf<_CharT, _Traits, _Allocator>::seekoff(off_type __off,
|
|||
if ((__wch & (ios_base::in | ios_base::out)) == (ios_base::in | ios_base::out)
|
||||
&& __way == ios_base::cur)
|
||||
return pos_type(-1);
|
||||
const ptrdiff_t __hm = __hm_ == nullptr ? 0 : __hm_ - __str_.data();
|
||||
off_type __noff;
|
||||
switch (__way)
|
||||
{
|
||||
|
@ -590,13 +591,13 @@ basic_stringbuf<_CharT, _Traits, _Allocator>::seekoff(off_type __off,
|
|||
__noff = this->pptr() - this->pbase();
|
||||
break;
|
||||
case ios_base::end:
|
||||
__noff = __hm_ - __str_.data();
|
||||
__noff = __hm;
|
||||
break;
|
||||
default:
|
||||
return pos_type(-1);
|
||||
}
|
||||
__noff += __off;
|
||||
if (__noff < 0 || __hm_ - __str_.data() < __noff)
|
||||
if (__noff < 0 || __hm < __noff)
|
||||
return pos_type(-1);
|
||||
if (__noff != 0)
|
||||
{
|
||||
|
|
|
@ -20,6 +20,30 @@
|
|||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
std::stringbuf sb(std::ios_base::in);
|
||||
assert(sb.pubseekoff(3, std::ios_base::beg, std::ios_base::out) == -1);
|
||||
assert(sb.pubseekoff(3, std::ios_base::cur, std::ios_base::out) == -1);
|
||||
assert(sb.pubseekoff(-3, std::ios_base::end, std::ios_base::out) == -1);
|
||||
assert(sb.pubseekoff(3, std::ios_base::beg, std::ios_base::in | std::ios_base::out) == -1);
|
||||
assert(sb.pubseekoff(3, std::ios_base::cur, std::ios_base::in | std::ios_base::out) == -1);
|
||||
assert(sb.pubseekoff(-3, std::ios_base::end, std::ios_base::in | std::ios_base::out) == -1);
|
||||
assert(sb.pubseekoff(0, std::ios_base::beg, std::ios_base::in) == 0);
|
||||
assert(sb.pubseekoff(0, std::ios_base::cur, std::ios_base::in) == 0);
|
||||
assert(sb.pubseekoff(0, std::ios_base::end, std::ios_base::in) == 0);
|
||||
}
|
||||
{
|
||||
std::stringbuf sb(std::ios_base::out);
|
||||
assert(sb.pubseekoff(3, std::ios_base::beg, std::ios_base::in) == -1);
|
||||
assert(sb.pubseekoff(3, std::ios_base::cur, std::ios_base::in) == -1);
|
||||
assert(sb.pubseekoff(-3, std::ios_base::end, std::ios_base::in) == -1);
|
||||
assert(sb.pubseekoff(3, std::ios_base::beg, std::ios_base::in | std::ios_base::out) == -1);
|
||||
assert(sb.pubseekoff(3, std::ios_base::cur, std::ios_base::in | std::ios_base::out) == -1);
|
||||
assert(sb.pubseekoff(-3, std::ios_base::end, std::ios_base::in | std::ios_base::out) == -1);
|
||||
assert(sb.pubseekoff(0, std::ios_base::beg, std::ios_base::out) == 0);
|
||||
assert(sb.pubseekoff(0, std::ios_base::cur, std::ios_base::out) == 0);
|
||||
assert(sb.pubseekoff(0, std::ios_base::end, std::ios_base::out) == 0);
|
||||
}
|
||||
{
|
||||
std::stringbuf sb("0123456789", std::ios_base::in);
|
||||
assert(sb.pubseekoff(3, std::ios_base::beg, std::ios_base::out) == -1);
|
||||
|
|
Loading…
Reference in New Issue