]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[BUG] fix buffer_skip() and buffer_si_getline() to correctly handle wrap-arounds
authorWilly Tarreau <w@1wt.eu>
Wed, 23 Sep 2009 20:56:07 +0000 (22:56 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 23 Sep 2009 21:52:14 +0000 (23:52 +0200)
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.

include/proto/buffers.h
src/buffers.c

index ab47b4f7cbbb0877d977feacd5e1878dd78346cc..3a4367894fa1fc5e60f0e7261481630ae23edc37 100644 (file)
@@ -331,13 +331,13 @@ static inline int buffer_contig_data(struct buffer *buf)
  * 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)
index dd5c00339e97b0eeda2c37233402113b04ccb1f0..724400f02e925dcac95e9e03fe915fdeb0657254 100644 (file)
@@ -151,7 +151,7 @@ int buffer_si_peekline(struct buffer *buf, char *str, int len)
 
        if (max > buf->send_max) {
                max = buf->send_max;
-               str[max] = 0;
+               str[max-1] = 0;
        }
        while (max) {
                *str++ = *p;
@@ -164,8 +164,9 @@ int buffer_si_peekline(struct buffer *buf, char *str, int len)
                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)