HTTPCLIENT-1767: Null pointer dereference in EofSensorInputStream and ResponseEntityProxy

EofSensorInputStream is generating NullPointerExceptions in some rare situations. This commit fixes that behaviour for the check methods by dereferencing the instance variable to a final local variable to ensure that if it is not null at the null guard, that it will be not null after that point also to successfully close/abort the stream

In some rare cases, null parameters are sent to ReponseEntityProxy methods, this adds checks on those to ensure that the connections are still released, but the null variable is not dereferenced.

Contributed by Peter Ansell <p_ansell@yahoo.com>

Conflicts:
	httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/ResponseEntityProxy.java

git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1760585 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Oleg Kalnichevski 2016-09-13 18:32:38 +00:00
parent f779a4b65d
commit 28a6d5c481
2 changed files with 21 additions and 12 deletions

View File

@ -92,7 +92,9 @@ class ResponseEntityProxy extends HttpEntityWrapper implements EofSensorWatcher
@Override
public void writeTo(final OutputStream outstream) throws IOException {
try {
super.writeTo(outstream);
if (outstream != null) {
super.writeTo(outstream);
}
releaseConnection();
} catch (IOException | RuntimeException ex) {
abortConnection();
@ -107,7 +109,9 @@ class ResponseEntityProxy extends HttpEntityWrapper implements EofSensorWatcher
try {
// there may be some cleanup required, such as
// reading trailers after the response body:
wrapped.close();
if (wrapped != null) {
wrapped.close();
}
releaseConnection();
} catch (IOException | RuntimeException ex) {
abortConnection();
@ -125,7 +129,9 @@ class ResponseEntityProxy extends HttpEntityWrapper implements EofSensorWatcher
// this assumes that closing the stream will
// consume the remainder of the response body:
try {
wrapped.close();
if (wrapped != null) {
wrapped.close();
}
releaseConnection();
} catch (final SocketException ex) {
if (open) {

View File

@ -193,14 +193,15 @@ public class EofSensorInputStream extends InputStream implements ConnectionRelea
*/
protected void checkEOF(final int eof) throws IOException {
if ((wrappedStream != null) && (eof < 0)) {
final InputStream toCheckStream = wrappedStream;
if ((toCheckStream != null) && (eof < 0)) {
try {
boolean scws = true; // should close wrapped stream?
if (eofWatcher != null) {
scws = eofWatcher.eofDetected(wrappedStream);
scws = eofWatcher.eofDetected(toCheckStream);
}
if (scws) {
wrappedStream.close();
toCheckStream.close();
}
} finally {
wrappedStream = null;
@ -221,14 +222,15 @@ public class EofSensorInputStream extends InputStream implements ConnectionRelea
*/
protected void checkClose() throws IOException {
if (wrappedStream != null) {
final InputStream toCloseStream = wrappedStream;
if (toCloseStream != null) {
try {
boolean scws = true; // should close wrapped stream?
if (eofWatcher != null) {
scws = eofWatcher.streamClosed(wrappedStream);
scws = eofWatcher.streamClosed(toCloseStream);
}
if (scws) {
wrappedStream.close();
toCloseStream.close();
}
} finally {
wrappedStream = null;
@ -251,14 +253,15 @@ public class EofSensorInputStream extends InputStream implements ConnectionRelea
*/
protected void checkAbort() throws IOException {
if (wrappedStream != null) {
final InputStream toAbortStream = wrappedStream;
if (toAbortStream != null) {
try {
boolean scws = true; // should close wrapped stream?
if (eofWatcher != null) {
scws = eofWatcher.streamAbort(wrappedStream);
scws = eofWatcher.streamAbort(toAbortStream);
}
if (scws) {
wrappedStream.close();
toAbortStream.close();
}
} finally {
wrappedStream = null;