This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch 9.0.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 0a2642d0ea785ae31a76d74e4b09d1c992b66ead Author: Mark Thomas <ma...@apache.org> AuthorDate: Wed Mar 4 15:05:00 2020 +0000 Additional fix for BZ 64192. https://bz.apache.org/bugzilla/show_bug.cgi?id=64192 It was noted during investigation of BZ 64192 that inconsistent values were being returned for the number of bytes read. --- .../apache/tomcat/util/net/SecureNio2Channel.java | 22 ++++++++++++++-------- .../apache/tomcat/util/net/SecureNioChannel.java | 22 ++++++++++++++-------- webapps/docs/changelog.xml | 4 +++- 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/java/org/apache/tomcat/util/net/SecureNio2Channel.java b/java/org/apache/tomcat/util/net/SecureNio2Channel.java index 54d9e03..d3a0b73 100644 --- a/java/org/apache/tomcat/util/net/SecureNio2Channel.java +++ b/java/org/apache/tomcat/util/net/SecureNio2Channel.java @@ -1011,13 +1011,11 @@ public class SecureNio2Channel extends Nio2Channel { SSLEngineResult unwrap; ByteBuffer[] dsts2 = dsts; int length2 = length; - boolean processOverflow = false; + OverflowState overflowState = OverflowState.NONE; do { - boolean useOverflow = false; - if (processOverflow) { - useOverflow = true; + if (overflowState == OverflowState.PROCESSING) { + overflowState = OverflowState.DONE; } - processOverflow = false; //prepare the buffer netInBuffer.flip(); //unwrap the data @@ -1027,7 +1025,7 @@ public class SecureNio2Channel extends Nio2Channel { if (unwrap.getStatus() == Status.OK || unwrap.getStatus() == Status.BUFFER_UNDERFLOW) { //we did receive some data, add it to our total read += unwrap.bytesProduced(); - if (useOverflow) { + if (overflowState == OverflowState.DONE) { // Remove the data read into the overflow buffer read -= getBufHandler().getReadBuffer().position(); } @@ -1091,14 +1089,15 @@ public class SecureNio2Channel extends Nio2Channel { } length2 = length + 1; getBufHandler().configureReadBufferForWrite(); - processOverflow = true; + overflowState = OverflowState.PROCESSING; } } else if (unwrap.getStatus() == Status.CLOSED) { break; } else { throw new IOException(sm.getString("channel.nio.ssl.unwrapFail", unwrap.getStatus())); } - } while ((netInBuffer.position() != 0) || processOverflow); //continue to unwrapping as long as the input buffer has stuff + } while ((netInBuffer.position() != 0 || overflowState == OverflowState.PROCESSING) && + overflowState != OverflowState.DONE); int capacity = 0; final int endOffset = offset + length; for (int i = offset; i < endOffset; i++) { @@ -1248,4 +1247,11 @@ public class SecureNio2Channel extends Nio2Channel { public ByteBuffer getEmptyBuf() { return emptyBuf; } + + + private enum OverflowState { + NONE, + PROCESSING, + DONE; + } } \ No newline at end of file diff --git a/java/org/apache/tomcat/util/net/SecureNioChannel.java b/java/org/apache/tomcat/util/net/SecureNioChannel.java index 7d128fb..1bd143f 100644 --- a/java/org/apache/tomcat/util/net/SecureNioChannel.java +++ b/java/org/apache/tomcat/util/net/SecureNioChannel.java @@ -683,13 +683,11 @@ public class SecureNioChannel extends NioChannel { int read = 0; //the SSL engine result SSLEngineResult unwrap; - boolean processOverflow = false; + OverflowState overflowState = OverflowState.NONE; do { - boolean useOverflow = false; - if (processOverflow) { - useOverflow = true; + if (overflowState == OverflowState.PROCESSING) { + overflowState = OverflowState.DONE; } - processOverflow = false; //prepare the buffer netInBuffer.flip(); //unwrap the data @@ -700,7 +698,7 @@ public class SecureNioChannel extends NioChannel { if (unwrap.getStatus() == Status.OK || unwrap.getStatus() == Status.BUFFER_UNDERFLOW) { //we did receive some data, add it to our total read += unwrap.bytesProduced(); - if (useOverflow) { + if (overflowState == OverflowState.DONE) { // Remove the data read into the overflow buffer read -= getBufHandler().getReadBuffer().position(); } @@ -760,14 +758,15 @@ public class SecureNioChannel extends NioChannel { dsts = dsts2; length++; getBufHandler().configureReadBufferForWrite(); - processOverflow = true; + overflowState = OverflowState.PROCESSING; } } } else { // Something else went wrong throw new IOException(sm.getString("channel.nio.ssl.unwrapFail", unwrap.getStatus())); } - } while (netInBuffer.position() != 0 || processOverflow); //continue to unwrapping as long as the input buffer has stuff + } while ((netInBuffer.position() != 0 || overflowState == OverflowState.PROCESSING) && + overflowState != OverflowState.DONE); return read; } @@ -884,4 +883,11 @@ public class SecureNioChannel extends NioChannel { public ByteBuffer getEmptyBuf() { return emptyBuf; } + + + private enum OverflowState { + NONE, + PROCESSING, + DONE; + } } diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 7ece63d..a7bf76f 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -135,7 +135,9 @@ </fix> <fix> <bug>64192</bug>: Correctly handle case where unread data is returned to - the read buffer when the read buffer is non empty. (markt) + the read buffer when the read buffer is non empty. Ensure a gathering + TLS read stops once the provided ByteBuffers are full or no more data is + available. (markt) </fix> <fix> <bug>64195</bug>: Revert simplification of NIO block read and write, --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org