From: Willy Tarreau Date: Wed, 23 Sep 2009 20:56:07 +0000 (+0200) Subject: [BUG] fix buffer_skip() and buffer_si_getline() to correctly handle wrap-arounds X-Git-Tag: v1.4-dev3~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2e1dd3d21350ad5eef7f688eee0c75e140430190;p=thirdparty%2Fhaproxy.git [BUG] fix buffer_skip() and buffer_si_getline() to correctly handle wrap-arounds 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. --- diff --git a/include/proto/buffers.h b/include/proto/buffers.h index ab47b4f7cb..3a4367894f 100644 --- a/include/proto/buffers.h +++ b/include/proto/buffers.h @@ -331,13 +331,13 @@ static inline int buffer_contig_data(struct buffer *buf) * Advance the buffer's read pointer by bytes. This is useful when data * have been read directly from the buffer. It is illegal to call this function * with causing a wrapping at the end of the buffer. It's the caller's - * responsibility to ensure that is never larger than buffer_contig_data. + * responsibility to ensure that 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) diff --git a/src/buffers.c b/src/buffers.c index dd5c00339e..724400f02e 100644 --- a/src/buffers.c +++ b/src/buffers.c @@ -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)