In h1_nego_ff(), when the output is chunked, some room may be reserved to emit
the chunk size later, in h1_done_ff(). However, when the producer's buffer is
not empty, a first copy may be performed via the b_xfer() function. At this
stage the buffers may be swapped while it is not expected. The reserved space
may be moved and the head position lost.
In practice, it is pretty hard to hit the bug.
Now the data are always copied when room is reserved, using b_force_xfer().
b_xfer() is still used when no room is reserved.
This was introduced by commit
e8cc8a60b in 3.1 (backported to 3.0). It
must be backported as far as 3.0.
if (xfer > b_data(input))
xfer = b_data(input);
- h1c->obuf.head += offset;
- h1s->sd->iobuf.data = b_xfer(&h1c->obuf, input, xfer);
- h1c->obuf.head -= offset;
+ if (offset) {
+ /* Room is reserved the chunk size, force the xfer to avoid any buffer swap */
+ h1c->obuf.head += offset;
+ h1s->sd->iobuf.data = b_force_xfer(&h1c->obuf, input, xfer);
+ h1c->obuf.head -= offset;
+ }
+ else
+ h1s->sd->iobuf.data = b_xfer(&h1c->obuf, input, xfer);
/* Cannot forward more data, wait for room */
if (b_data(input))