mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2026-01-17 06:41:00 +01:00
[MINOR] buffer_replace2 must never change the ->w entry
This function is used to move data which is located between ->w and ->r, so it must not touch ->w, otherwise it will displace pending data which is before the one we're actually overwriting. The issue arose in 1.4 with some pipelined responses which cause some part of the previous one to be chopped off when removing the connection: close header, thus corrupting last response and shifting next one. Those are detected in the logs because the next response will be a 502 with flags PH. Note that this does not affect 1.3, still this is a bug that's better fixed than blindly copy-pasted and woken up again. (cherry picked from commit bbfa7938bd74adbfa435f26503fc10f5938195a3)
This commit is contained in:
parent
857d0c3d0c
commit
c65cbb7095
@ -98,7 +98,7 @@ int buffer_write_chunk(struct buffer *buf, struct chunk *chunk)
|
||||
/*
|
||||
* this function writes the string <str> at position <pos> which must be in buffer <b>,
|
||||
* and moves <end> just after the end of <str>.
|
||||
* <b>'s parameters (l, r, w, h, lr) are recomputed to be valid after the shift.
|
||||
* <b>'s parameters (l, r, lr) are recomputed to be valid after the shift.
|
||||
* the shift value (positive or negative) is returned.
|
||||
* If there's no space left, the move is not done.
|
||||
*
|
||||
@ -114,6 +114,9 @@ int buffer_replace(struct buffer *b, char *pos, char *end, const char *str)
|
||||
if (delta + b->r >= b->data + BUFSIZE)
|
||||
return 0; /* no space left */
|
||||
|
||||
if (delta + b->r > b->w && b->w >= b->r && b->l)
|
||||
return 0; /* no space left before wrapping data */
|
||||
|
||||
/* first, protect the end of the buffer */
|
||||
memmove(end + delta, end, b->r - end);
|
||||
|
||||
@ -122,7 +125,6 @@ int buffer_replace(struct buffer *b, char *pos, char *end, const char *str)
|
||||
|
||||
/* we only move data after the displaced zone */
|
||||
if (b->r > pos) b->r += delta;
|
||||
if (b->w > pos) b->w += delta;
|
||||
if (b->lr > pos) b->lr += delta;
|
||||
b->l += delta;
|
||||
|
||||
@ -148,6 +150,9 @@ int buffer_replace2(struct buffer *b, char *pos, char *end, const char *str, int
|
||||
if (delta + b->r >= b->data + BUFSIZE)
|
||||
return 0; /* no space left */
|
||||
|
||||
if (delta + b->r > b->w && b->w >= b->r && b->l)
|
||||
return 0; /* no space left before wrapping data */
|
||||
|
||||
/* first, protect the end of the buffer */
|
||||
memmove(end + delta, end, b->r - end);
|
||||
|
||||
@ -157,7 +162,6 @@ int buffer_replace2(struct buffer *b, char *pos, char *end, const char *str, int
|
||||
|
||||
/* we only move data after the displaced zone */
|
||||
if (b->r > pos) b->r += delta;
|
||||
if (b->w > pos) b->w += delta;
|
||||
if (b->lr > pos) b->lr += delta;
|
||||
b->l += delta;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user