< Previous by Date Date Index Next by Date >
  Thread Index  

[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