[Bug libstdc++/28759] New: stringbuf writes beyond external buffer given via pubsetbuf()

ngiff at yahoo dot com gcc-bugzilla@gcc.gnu.org
Thu Aug 17 00:53:00 GMT 2006


$ gcc -v
Reading specs from /usr/lib/gcc/i386-redhat-linux/3.4.5/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
--infodir=/usr/share/info --enable-shared --enable-threads=posix
--disable-checking --with-system-zlib --enable-__cxa_atexit
--disable-libunwind-exceptions --enable-java-awt=gtk --host=i386-redhat-linux
Thread model: posix
gcc version 3.4.5 20051201 (Red Hat 3.4.5-2)

$ uname -a
Linux localhost.localdomain 2.6.9-34.0.1.EL #1 Wed May 24 07:40:56 CDT 2006
i686 i686 i386 GNU/Linux


I encounter this bug when using ostringstream with an external buffer.

When an external buffer is given to pubsetbuf(), it is copied into the internal
buffer (_M_string).  (The code comments in sstream indicate that it thinks it's
destroying the buffer, but it's not.)  If the size of the external buffer is <=
115, everything is fine.  Above that, the internal buffer allocates additional
storage in 128 byte increments (227, 355, ...), which increases its capacity()
beyond its size().  The second step of pubsetbuf() calls _M_sync() to set up
the put/get pointers.  However, setp() is then called with the external buffer
pointer as the first argument (correct) and ((buffer pointer) +
_M_string.capacity()) as the second (incorrect).  This capacity() is greater
than the size of the external buffer, so the end put pointer points well past
the end of the external buffer.

In the following example, a size of 116 is given to pubsetbuf().  However, the
capacity of the internal buffer is 227.  227 'x' chars get written into the
external buffer.

#include <iostream>
#include <sstream>

using namespace std;

int main() {
    ostringstream oss;
    char *buf = new char[256];
    memset(buf, 0, sizeof(buf));

    oss.rdbuf()->pubsetbuf(buf, 116);
    cout << "INTERAL BUFF SIZE " << oss.str().size() << " " <<
oss.str().capacity() << endl;

    for (int i=0; i<1000; i++)
    {
        oss << "x";
    }
    oss.rdbuf()->pubsetbuf(0, 0);

    cout << "EXTNERAL BUFF SIZE " << strlen(buf) << endl;
}


Let me know if I can provide any other info...
Nick


-- 
           Summary: stringbuf writes beyond external buffer given via
                    pubsetbuf()
           Product: gcc
           Version: 3.4.5
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: ngiff at yahoo dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28759



More information about the Gcc-bugs mailing list