[reSIProcate] nasty DataBuffer bug
There is a nasty little bug in DataBuffer (in DataStream.cxx).
Particularly, we are looking at the overflow(int c) method, and its
partner sync().
*snip*
int
DataBuffer::sync()
{
size_t len = pptr() - pbase();
if (len > 0)
{
size_t pos = gptr() - eback(); // remember the get position
mStr.mSize += len;
char* gbuf = const_cast<char*>(mStr.data());
// reset the get buffer
setg(gbuf, gbuf+pos, gbuf+mStr.size());
// reset the put buffer
setp(gbuf + mStr.mSize, gbuf + mStr.mCapacity);
}
return 0;
}
int
DataBuffer::overflow(int c)
{
// sync, but reallocate
size_t len = pptr() - pbase();
if (len > 0)
{
size_t pos = gptr() - eback(); // remember the get position
// update the length
mStr.mSize += len;
// resize the underlying Data and reset the input buffer
mStr.resize(((mStr.mCapacity+16)*3)/2, true);
char* gbuf = const_cast<char*>(mStr.mBuf);
// reset the get buffer
setg(gbuf, gbuf+pos, gbuf+mStr.mSize);
// reset the put buffer
setp(gbuf + mStr.mSize, gbuf + mStr.mCapacity);
}
if (c != -1)
{
mStr.mBuf[mStr.mSize] = c;
pbump(1);
return c;
}
return 0;
}
*snip*
In the event that the buffer has been filled _exactly_ to capacity,
and then flushed, sync causes the put buffer to have zero length. As
a result, when we try to write some more (immediately triggering a
call to overflow), we don't fall into the block of code that resizes
the buffer, and then pbump gets called, incrementing the put pointer
_past_ the end of the buffer. All we should need to do to fix this,
however, is test len >= 0 in overflow() instead.
Best regards,
Byron Campen