You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2023/07/24 14:26:49 UTC
[tomcat] branch 10.1.x updated: Fix BZ 66681 - NPE on batch flush when permessage-deflate enabled
This is an automated email from the ASF dual-hosted git repository.
markt pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/10.1.x by this push:
new 978ff4af95 Fix BZ 66681 - NPE on batch flush when permessage-deflate enabled
978ff4af95 is described below
commit 978ff4af95a78ba06208e387c6613008627f3c66
Author: Mark Thomas <ma...@apache.org>
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 665cfd24f4..6e6797d812 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 a8301c8277..51f3b31e28 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 3a9a5e18b7..460ea09733 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -124,6 +124,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>
</section>
<section name="Tomcat 10.1.11 (schultz)" rtext="Released 2023-07-10">
<subsection name="Catalina">
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org