[reSIProcate] nasty DataBuffer bug

Byron Campen bcampen at estacado.net
Fri Sep 23 10:06:43 CDT 2005


     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



More information about the resiprocate-devel mailing list