This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

libstdc++/10101: [3.0/3.2/3.3/3.4 regression] seekp() on std::strstream can break reading back from the stream


>Number:         10101
>Category:       libstdc++
>Synopsis:       [3.0/3.2/3.3/3.4 regression] seekp() on std::strstream can break reading back from the stream
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Mar 15 16:56:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator:     Andrew Pollard
>Release:        gcc-3_0-branch, gcc-3_2-branch, gcc-3_3-branch, gcc head
>Organization:
>Environment:
RedHat8.0/PIII system
Sun Sparc Solaris2.6/2.8
>Description:
I know that std::strstream is deprecated, but I've come across (what I'm pretty sure is) a bug in it, which would be nice to fix (pseudo patch attached in the 'Fix' section)

The following code:

strstream.cxx:
-------------------------
#include <strstream>
#include <string>
#include <iostream>

int
main()
{
    std::strstream s;
    s << "Hello" << std::ends;

    s.seekp(0, std::ios::beg);
    s.seekg(0, std::ios::beg);

    std::string str;
    s >> str;

    std::cout << str << std::endl;
    return (0);
}
-----------------------

Doesn't print out "Hello", but prints nothing.

It works if a std::stringstream is used instead.

It also works if the seekp() is removed.

It works with gcc-2.95, MSVC++6.0 and Intel icc-7.0.

Basically, if you seekp() the writing position, when strstreambuf::underflow next is called, and the pptr() is now past egptr(), then egptr() is set to pptr().

This has the effect that if you write into a strstream, and don't read anything from it (egptr() == eback()), when you seekp(0, std::ios::beg), you then cannot read the written data out of the stream, since egptr() == eback(), causing underflow, which doesn't change egptr(), and thus you get
_Traits::eof() returned.

This worked in gcc-2.95 since the implementation was completly different (using libio). Interestingly STLport has the same problem, looks like this might be a "day 1" SGI STL bug...
>How-To-Repeat:

>Fix:
I think it is a simple change to strstreambuf::underflow()
[ libstdc++-v3/src/strstream.cc ]

This is the code from the gcc-3_2-branch:

  strstreambuf::int_type
  strstreambuf::underflow()
  {
    if (gptr() == egptr() && pptr() && pptr() > egptr())
      setg(eback(), gptr(), pptr());

    if (gptr() != egptr())
      return (unsigned char) *gptr();
    else
      return _Traits::eof();
  }

[ same for gcc-3.0/3.3/3.4 ]

Changing the pptr()'s to epptr()'s appears to fix the problem, ie

    if (gptr() == egptr() && epptr() && epptr() > egptr())
      setg(eback(), gptr(), epptr());

ie, if the end of the current writing buffer is past the current end of the reading buffer, set the reading buffer to the current writing buffer.

Looking at the gcc-2.95 sources, and what std::stringstream does, this seems to be an equivalent implementation.
>Release-Note:
>Audit-Trail:
>Unformatted:


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]