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
The following commit(s) were added to refs/heads/9.0.x by this push:
new 0ed01f7726 Fix BZ 66681 - NPE on batch flush when permessage-deflate
enabled
0ed01f7726 is described below
commit 0ed01f7726cace0804b1c9cda78687cf87953777
Author: Mark Thomas <[email protected]>
AuthorDate: Mon Jul 24 15:26:24 2023 +0100
Fix BZ 66681 - NPE on batch flush when permessage-deflate enabled
https://bz.apache.org/bugzilla/show_bug.cgi?id=66681
---
.../apache/tomcat/websocket/PerMessageDeflate.java | 11 +++--
.../tomcat/websocket/TestPerMessageDeflate.java | 49 ++++++++++++++++++++++
webapps/docs/changelog.xml | 9 ++++
3 files changed, 65 insertions(+), 4 deletions(-)
diff --git a/java/org/apache/tomcat/websocket/PerMessageDeflate.java
b/java/org/apache/tomcat/websocket/PerMessageDeflate.java
index a7a9fb4524..32594c6b17 100644
--- a/java/org/apache/tomcat/websocket/PerMessageDeflate.java
+++ b/java/org/apache/tomcat/websocket/PerMessageDeflate.java
@@ -314,13 +314,16 @@ public class PerMessageDeflate implements Transformation {
for (MessagePart uncompressedPart : uncompressedParts) {
byte opCode = uncompressedPart.getOpCode();
- boolean emptyPart = uncompressedPart.getPayload().limit() == 0;
- emptyMessage = emptyMessage && emptyPart;
if (Util.isControl(opCode)) {
// Control messages can appear in the middle of other messages
- // and must not be compressed. Pass it straight through
+ // and must not be compressed. Pass it straight through.
allCompressedParts.add(uncompressedPart);
- } else if (emptyMessage && uncompressedPart.isFin()) {
+ continue;
+ }
+
+ boolean emptyPart = uncompressedPart.getPayload().limit() == 0;
+ emptyMessage = emptyMessage && emptyPart;
+ if (emptyMessage && uncompressedPart.isFin()) {
// Zero length messages can't be compressed so pass the
// final (empty) part straight through.
allCompressedParts.add(uncompressedPart);
diff --git a/test/org/apache/tomcat/websocket/TestPerMessageDeflate.java
b/test/org/apache/tomcat/websocket/TestPerMessageDeflate.java
index 2f01440186..d2a420cffc 100644
--- a/test/org/apache/tomcat/websocket/TestPerMessageDeflate.java
+++ b/test/org/apache/tomcat/websocket/TestPerMessageDeflate.java
@@ -101,6 +101,55 @@ public class TestPerMessageDeflate {
}
+ /*
+ * https://bz.apache.org/bugzilla/show_bug.cgi?id=66681
+ */
+ @Test
+ public void testFlushBatchMessagePart() throws IOException {
+ // Set up the extension using defaults
+ List<Parameter> parameters = Collections.emptyList();
+ List<List<Parameter>> preferences = new ArrayList<>();
+ preferences.add(parameters);
+
+ // Set up the compression and sending of the message.
+ PerMessageDeflate perMessageDeflateTx =
PerMessageDeflate.negotiate(preferences, true);
+ perMessageDeflateTx.setNext(new TesterTransformation());
+
+ List<MessagePart> uncompressedParts = new ArrayList<>();
+
+ // First message part
+ byte[] data = new byte[1024];
+ ByteBuffer bb = ByteBuffer.wrap(data);
+ MessagePart mp1 = new MessagePart(true, 0, Constants.OPCODE_BINARY,
bb, null, null, -1);
+ uncompressedParts.add(mp1);
+
+ // Flush message (replicates result of calling flushBatch()
+ MessagePart mp2 = new MessagePart(true, 0,
Constants.INTERNAL_OPCODE_FLUSH, null, null, null, -1);
+ uncompressedParts.add(mp2);
+
+ List<MessagePart> compressedParts =
perMessageDeflateTx.sendMessagePart(uncompressedParts);
+
+ Assert.assertEquals(2, compressedParts.size());
+
+ // Check the first compressed part
+ MessagePart compressedPart1 = compressedParts.get(0);
+
+ // Set up the decompression and process the received message
+ PerMessageDeflate perMessageDeflateRx =
PerMessageDeflate.negotiate(preferences, true);
+ perMessageDeflateRx.setNext(new
TesterTransformation(compressedPart1.getPayload()));
+
+ ByteBuffer received = ByteBuffer.allocate(8192);
+
+ TransformationResult tr =
perMessageDeflateRx.getMoreData(compressedPart1.getOpCode(),
compressedPart1.isFin(),
+ compressedPart1.getRsv(), received);
+
+ Assert.assertEquals(1024, received.position());
+ Assert.assertEquals(TransformationResult.END_OF_FRAME, tr);
+
+ // Check the second compressed part (should be passed through
unchanged)
+ Assert.assertEquals(mp2, compressedParts.get(1));
+ }
+
/*
* Minimal implementation to enable other transformations to be tested. It
is NOT robust.
*/
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 14f12ac999..3d7f7256a8 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -145,6 +145,15 @@
</fix>
</changelog>
</subsection>
+ <subsection name="WebSocket">
+ <changelog>
+ <fix>
+ <bug>66681</bug>: Fix a <code>NullPointerException</code> when flushing
+ batched messages with compression enabled using
+ <code>permessage-deflate</code>. (markt)
+ </fix>
+ </changelog>
+ </subsection>
<subsection name="Other">
<changelog>
<fix>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]