BUG/MEDIUM: filters: Fix data filtering when data are modified

Filters can alter data during the parsing, i.e when http_data or tcp_data
callbacks are called. For now, the update must be done by hand. So we must
handle changes in the channel buffers, especially on the number of input bytes
pending (buf->i).
In addition, a filter can choose to switch channel buffers to do its
updates. So, during data filtering, we must always use the right buffer and not
use variable to reference them.

Without this patch, filters cannot safely alter data during the data parsing.
diff --git a/src/filters.c b/src/filters.c
index 139440d..7f8fae4 100644
--- a/src/filters.c
+++ b/src/filters.c
@@ -418,12 +418,11 @@
 flt_http_data(struct stream *s, struct http_msg *msg)
 {
 	struct filter *filter;
-	struct buffer *buf = msg->chn->buf;
 	unsigned int   buf_i;
-	int            ret = 0;
+	int            delta = 0, ret = 0;
 
 	/* Save buffer state */
-	buf_i = buf->i;
+	buf_i = msg->chn->buf->i;
 
 	list_for_each_entry(filter, &strm_flt(s)->filters, list) {
 		unsigned int *nxt;
@@ -440,9 +439,12 @@
 			*nxt = msg->next;
 
 		if (FLT_OPS(filter)->http_data) {
+			unsigned int i = msg->chn->buf->i;
+
 			ret = FLT_OPS(filter)->http_data(s, filter, msg);
 			if (ret < 0)
 				break;
+			delta += (int)(msg->chn->buf->i - i);
 
 			/* Update the next offset of the current filter */
 			*nxt += ret;
@@ -450,18 +452,18 @@
 			/* And set this value as the bound for the next
 			 * filter. It will not able to parse more data than this
 			 * one. */
-			buf->i = *nxt;
+			msg->chn->buf->i = *nxt;
 		}
 		else {
 			/* Consume all available data and update the next offset
 			 * of the current filter. buf->i is untouched here. */
-			ret = MIN(msg->chunk_len + msg->next, buf->i) - *nxt;
+			ret = MIN(msg->chunk_len + msg->next, msg->chn->buf->i) - *nxt;
 			*nxt += ret;
 		}
 	}
 
 	/* Restore the original buffer state */
-	buf->i = buf_i;
+	msg->chn->buf->i = buf_i + delta;
 
 	return ret;
 }
@@ -806,12 +808,11 @@
 flt_data(struct stream *s, struct channel *chn)
 {
 	struct filter *filter;
-	struct buffer *buf = chn->buf;
 	unsigned int   buf_i;
-	int            ret = 0;
+	int            delta = 0, ret = 0;
 
 	/* Save buffer state */
-	buf_i = buf->i;
+	buf_i = chn->buf->i;
 
 	list_for_each_entry(filter, &strm_flt(s)->filters, list) {
 		unsigned int *nxt;
@@ -822,9 +823,12 @@
 
 		nxt = &FLT_NXT(filter, chn);
 		if (FLT_OPS(filter)->tcp_data) {
+			unsigned int i = chn->buf->i;
+
 			ret = FLT_OPS(filter)->tcp_data(s, filter, chn);
 			if (ret < 0)
 				break;
+			delta += (int)(chn->buf->i - i);
 
 			/* Increase next offset of the current filter */
 			*nxt += ret;
@@ -832,11 +836,11 @@
 			/* And set this value as the bound for the next
 			 * filter. It will not able to parse more data than the
 			 * current one. */
-			buf->i = *nxt;
+			chn->buf->i = *nxt;
 		}
 		else {
 			/* Consume all available data */
-			*nxt = buf->i;
+			*nxt = chn->buf->i;
 		}
 
 		/* Update <ret> value to be sure to have the last one when we
@@ -846,7 +850,7 @@
 	}
 
 	/* Restore the original buffer state */
-	chn->buf->i = buf_i;
+	chn->buf->i = buf_i + delta;
 
 	return ret;
 }