Those two functions did not correctly deal with full buffers and/or
buffers that wrapped around. Buffer_skip() was even able to incorrectly
set buf->w further than the end of buffer if its len argument was wrong,
and buffer_si_getline() was able to incorrectly return a length larger
than the effective buffer data available.
* Advance the buffer's read pointer by <len> bytes. This is useful when data
* have been read directly from the buffer. It is illegal to call this function
* with <len> causing a wrapping at the end of the buffer. It's the caller's
- * responsibility to ensure that <len> is never larger than buffer_contig_data.
+ * responsibility to ensure that <len> is never larger than buf->send_max.
*/
static inline void buffer_skip(struct buffer *buf, int len)
{
buf->w += len;
- if (buf->w == buf->data + buf->size)
- buf->w = buf->data; /* wrap around the buffer */
+ if (buf->w >= buf->data + buf->size)
+ buf->w -= buf->size; /* wrap around the buffer */
buf->l -= len;
if (!buf->l)
if (max > buf->send_max) {
max = buf->send_max;
- str[max] = 0;
+ str[max-1] = 0;
}
while (max) {
*str++ = *p;
if (p == buf->data + buf->size)
p = buf->data;
}
- if (*p != '\n' && ret < len && ret < buf->max_len &&
- !(buf->flags & (BF_SHUTW|BF_SHUTW_NOW)))
+ if (ret > 0 && ret < len && ret < buf->send_max &&
+ *(str-1) != '\n' &&
+ !(buf->flags & (BF_SHUTW|BF_SHUTW_NOW)))
ret = 0;
out:
if (max)