Skip to content

Commit 22c651c

Browse files
committedDec 19, 2017
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
1 parent 7e13aef commit 22c651c

File tree

2 files changed

+27
-2
lines changed

2 files changed

+27
-2
lines changed
 

‎libcxx/include/sstream

+3-2
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,7 @@ basic_stringbuf<_CharT, _Traits, _Allocator>::seekoff(off_type __off,
577577
if ((__wch & (ios_base::in | ios_base::out)) == (ios_base::in | ios_base::out)
578578
&& __way == ios_base::cur)
579579
return pos_type(-1);
580+
const ptrdiff_t __hm = __hm_ == nullptr ? 0 : __hm_ - __str_.data();
580581
off_type __noff;
581582
switch (__way)
582583
{
@@ -590,13 +591,13 @@ basic_stringbuf<_CharT, _Traits, _Allocator>::seekoff(off_type __off,
590591
__noff = this->pptr() - this->pbase();
591592
break;
592593
case ios_base::end:
593-
__noff = __hm_ - __str_.data();
594+
__noff = __hm;
594595
break;
595596
default:
596597
return pos_type(-1);
597598
}
598599
__noff += __off;
599-
if (__noff < 0 || __hm_ - __str_.data() < __noff)
600+
if (__noff < 0 || __hm < __noff)
600601
return pos_type(-1);
601602
if (__noff != 0)
602603
{

‎libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.virtuals/seekoff.pass.cpp

+24
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,30 @@
2020

2121
int main()
2222
{
23+
{
24+
std::stringbuf sb(std::ios_base::in);
25+
assert(sb.pubseekoff(3, std::ios_base::beg, std::ios_base::out) == -1);
26+
assert(sb.pubseekoff(3, std::ios_base::cur, std::ios_base::out) == -1);
27+
assert(sb.pubseekoff(-3, std::ios_base::end, std::ios_base::out) == -1);
28+
assert(sb.pubseekoff(3, std::ios_base::beg, std::ios_base::in | std::ios_base::out) == -1);
29+
assert(sb.pubseekoff(3, std::ios_base::cur, std::ios_base::in | std::ios_base::out) == -1);
30+
assert(sb.pubseekoff(-3, std::ios_base::end, std::ios_base::in | std::ios_base::out) == -1);
31+
assert(sb.pubseekoff(0, std::ios_base::beg, std::ios_base::in) == 0);
32+
assert(sb.pubseekoff(0, std::ios_base::cur, std::ios_base::in) == 0);
33+
assert(sb.pubseekoff(0, std::ios_base::end, std::ios_base::in) == 0);
34+
}
35+
{
36+
std::stringbuf sb(std::ios_base::out);
37+
assert(sb.pubseekoff(3, std::ios_base::beg, std::ios_base::in) == -1);
38+
assert(sb.pubseekoff(3, std::ios_base::cur, std::ios_base::in) == -1);
39+
assert(sb.pubseekoff(-3, std::ios_base::end, std::ios_base::in) == -1);
40+
assert(sb.pubseekoff(3, std::ios_base::beg, std::ios_base::in | std::ios_base::out) == -1);
41+
assert(sb.pubseekoff(3, std::ios_base::cur, std::ios_base::in | std::ios_base::out) == -1);
42+
assert(sb.pubseekoff(-3, std::ios_base::end, std::ios_base::in | std::ios_base::out) == -1);
43+
assert(sb.pubseekoff(0, std::ios_base::beg, std::ios_base::out) == 0);
44+
assert(sb.pubseekoff(0, std::ios_base::cur, std::ios_base::out) == 0);
45+
assert(sb.pubseekoff(0, std::ios_base::end, std::ios_base::out) == 0);
46+
}
2347
{
2448
std::stringbuf sb("0123456789", std::ios_base::in);
2549
assert(sb.pubseekoff(3, std::ios_base::beg, std::ios_base::out) == -1);

0 commit comments

Comments
 (0)
Please sign in to comment.