Issue #4828 Buffer Corruption (#4864)

+ improve synchronization around releaseBuffer
 + improve synchronization around acquireBuffer
 + made acquireBuffer private.

Signed-off-by: Greg Wilkins <gregw@webtide.com>
This commit is contained in:
Greg Wilkins 2020-05-11 21:48:06 +02:00 committed by GitHub
parent 933ab641ee
commit e86977394e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 14 additions and 8 deletions

View File

@ -487,8 +487,8 @@ public class HttpOutput extends ServletOutputStream implements Runnable
synchronized (_channelState)
{
_state = State.CLOSED;
releaseBuffer();
}
releaseBuffer();
}
@Override
@ -613,10 +613,13 @@ public class HttpOutput extends ServletOutputStream implements Runnable
public ByteBuffer getBuffer()
{
return _aggregate;
synchronized (_channelState)
{
return acquireBuffer();
}
}
public ByteBuffer acquireBuffer()
private ByteBuffer acquireBuffer()
{
if (_aggregate == null)
_aggregate = _channel.getByteBufferPool().acquire(getBufferSize(), _interceptor.isOptimizedForDirectBuffers());
@ -1410,10 +1413,13 @@ public class HttpOutput extends ServletOutputStream implements Runnable
public void resetBuffer()
{
_interceptor.resetBuffer();
if (BufferUtil.hasContent(_aggregate))
BufferUtil.clear(_aggregate);
_written = 0;
synchronized (_channelState)
{
_interceptor.resetBuffer();
if (BufferUtil.hasContent(_aggregate))
BufferUtil.clear(_aggregate);
_written = 0;
}
}
@Override

View File

@ -305,7 +305,7 @@ public class ErrorHandler extends AbstractHandler
// TODO error page may cause a BufferOverflow. In which case we try
// TODO again with stacks disabled. If it still overflows, it is
// TODO written without a body.
ByteBuffer buffer = baseRequest.getResponse().getHttpOutput().acquireBuffer();
ByteBuffer buffer = baseRequest.getResponse().getHttpOutput().getBuffer();
ByteBufferOutputStream out = new ByteBufferOutputStream(buffer);
PrintWriter writer = new PrintWriter(new OutputStreamWriter(out, charset));