From 2215a3c93bf8789a89fd6495f03e082dc6b1a638 Mon Sep 17 00:00:00 2001 From: Henning Schmiedehausen Date: Mon, 17 Sep 2018 12:22:15 -0700 Subject: [PATCH] Fix observed NPE in clearInputStream Under load, we observe NPEs like this in our log files with the 8.0.12 driver: Caused by: java.lang.NullPointerException: null at com.mysql.cj.protocol.a.NativeProtocol.clearInputStream(NativeProtocol.java:827) at com.mysql.cj.NativeSession.clearInputStream(NativeSession.java:335) at com.mysql.cj.jdbc.ServerPreparedStatement.serverPrepare(ServerPreparedStatement.java:659) at com.mysql.cj.jdbc.ServerPreparedStatement.(ServerPreparedStatement.java:133) at com.mysql.cj.jdbc.ServerPreparedStatement.getInstance(ServerPreparedStatement.java:102) at com.mysql.cj.jdbc.ConnectionImpl.prepareStatement(ConnectionImpl.java:1649) at com.mysql.cj.jdbc.ConnectionImpl.prepareStatement(ConnectionImpl.java:1583) [...] This is dereferencing the socketConnection.getMysqlInput() input stream as the this.socketConnection field only gets assigned once and never overridden. This patch adds a null check to the while condition so that a null value is not dereferenced. --- .../java/com/mysql/cj/protocol/a/NativeProtocol.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/protocol-impl/java/com/mysql/cj/protocol/a/NativeProtocol.java b/src/main/protocol-impl/java/com/mysql/cj/protocol/a/NativeProtocol.java index 66158f91..a762f600 100644 --- a/src/main/protocol-impl/java/com/mysql/cj/protocol/a/NativeProtocol.java +++ b/src/main/protocol-impl/java/com/mysql/cj/protocol/a/NativeProtocol.java @@ -95,6 +95,7 @@ import com.mysql.cj.protocol.AuthenticationProvider; import com.mysql.cj.protocol.ColumnDefinition; import com.mysql.cj.protocol.ExportControlled; +import com.mysql.cj.protocol.FullReadInputStream; import com.mysql.cj.protocol.Message; import com.mysql.cj.protocol.MessageReader; import com.mysql.cj.protocol.MessageSender; @@ -824,7 +825,8 @@ public void clearInputStream() { // Due to a bug in some older Linux kernels (fixed after the patch "tcp: fix FIONREAD/SIOCINQ"), our SocketInputStream.available() may return 1 even // if there is no data in the Stream, so, we need to check if InputStream.skip() actually skipped anything. - while ((len = this.socketConnection.getMysqlInput().available()) > 0 && this.socketConnection.getMysqlInput().skip(len) > 0) { + FullReadInputStream inputStream = this.socketConnection.getMysqlInput(); + while (inputStream != null && (len = inputStream.available()) > 0 && inputStream.skip(len) > 0) { continue; } } catch (IOException ioEx) {