Mark,

On 1/30/23 10:04, ma...@apache.org wrote:
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 08443cd8ac Fix BZ 66455 - avoid ClassCastException when processing 
window update
08443cd8ac is described below

commit 08443cd8acb3c82cde7e28f13c7a95dd08547e44
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Mon Jan 30 11:57:20 2023 +0000

     Fix BZ 66455 - avoid ClassCastException when processing window update
https://bz.apache.org/bugzilla/show_bug.cgi?id=66455
---
  .../apache/coyote/http2/Http2UpgradeHandler.java   |  2 +-
  .../apache/coyote/http2/TestHttp2Section_5_3.java  | 50 ++++++++++++++++++++++
  webapps/docs/changelog.xml                         |  6 +++
  3 files changed, 57 insertions(+), 1 deletion(-)

diff --git a/java/org/apache/coyote/http2/Http2UpgradeHandler.java 
b/java/org/apache/coyote/http2/Http2UpgradeHandler.java
index c14eeafc08..f38b8beb90 100644
--- a/java/org/apache/coyote/http2/Http2UpgradeHandler.java
+++ b/java/org/apache/coyote/http2/Http2UpgradeHandler.java
@@ -1037,13 +1037,13 @@ class Http2UpgradeHandler extends AbstractStream 
implements InternalHttpUpgradeH
                  if (stream.getConnectionAllocationRequested() > 0) {
                      
stream.setConnectionAllocationMade(stream.getConnectionAllocationRequested());
                      stream.setConnectionAllocationRequested(0);
+                    result.add(stream);
                  }
              }
              remaining -= backLogSize;
              backLogSize = 0;
              super.incrementWindowSize(remaining);
- result.addAll(backLogStreams);
              backLogStreams.clear();
          } else {
              allocate(this, remaining);
diff --git a/test/org/apache/coyote/http2/TestHttp2Section_5_3.java 
b/test/org/apache/coyote/http2/TestHttp2Section_5_3.java
index 32fdb9fed6..4a50528dd6 100644
--- a/test/org/apache/coyote/http2/TestHttp2Section_5_3.java
+++ b/test/org/apache/coyote/http2/TestHttp2Section_5_3.java
@@ -242,6 +242,56 @@ public class TestHttp2Section_5_3 extends Http2TestBase {
      }
+ @Test
+    public void testReleaseFullBacklog() throws Exception {
+
+        http2Connect();
+
+        // This test uses small window updates that will trigger the excessive
+        // overhead protection so disable it.
+        http2Protocol.setOverheadWindowUpdateThreshold(0);
+        // May also see (rarely, depends on timing) sequential 1 byte data
+        // frames on the same Stream
+        http2Protocol.setOverheadDataThreshold(0);
+
+
+        // Default connection window size is 64k - 1. Initial request will have
+        // used 8k (56k -1). Increase it to 57k
+        sendWindowUpdate(0, 1 + 1024);
+
+        // Use up 56k of the connection window
+        for (int i = 3; i < 17; i += 2) {
+            sendSimpleGetRequest(i);
+            readSimpleGetResponse();
+        }

All of the above numbers look bonkers. Surely some of it has to do with the fact that I don;t understand the underlying implementation.

Is the default window size really 65535 bytes (64k - 1)? That would be very unusual (is this some kind of spec-mandated window size? still seems weird). It seems more likely that it is a full 64k bytes and that the max index into that array would be 64k - 1.

How does sending a window update of 1025 increase the connection window size to 57k? Why won't 1024 do it? Or 512? Or 1024 * 57? Or (64 - 8) * 1024 - 1?

How does sending 7 updates with odd i values between 3 and 17 fill the first 56k of the connection window? Why use 3 - 17 instead of 0 - 6? Or, if you need some single-digit i values and some double-digits, why not use more straightforward loop bounds. It just looks very strange with no explanation.

I hope these questions aren't just annoying. I'm sure you know what you are doing. But I know if I was looking at this code to figure out why the unit test was failing in the future, I would be at a serious loss to understand what it was even doing in the first place.

-chris

+
+        output.clearTrace();
+
+        // At this point the connection window should be 1k and any new stream
+        // should have a window of 64k
+
+        // Create priority tree. This test requires a blocked stream to depend 
on a closed stream
+        sendPriority(17,  15, 15);
+
+        // Process a request on stream 17.
+        // This should consume the connection window and put streams 15 and 17 
in the backlog.
+        sendSimpleGetRequest(17);
+        // 17-headers, 17-1k-body
+        parser.readFrame();
+        parser.readFrame();
+        output.clearTrace();
+
+        // At this point 17 is blocked because the connection window is zero
+
+        // Send a large enough Window update to free the whole backlog
+        sendWindowUpdate(0, 8 * 1024);
+
+        parser.readFrame();
+
+        Assert.assertEquals("17-Body-7168\n17-EndOfStream\n", 
output.getTrace());
+    }
+
+
      private int[] parseBodyFrame(String output) {
          String[] parts = output.trim().split("-");
          if (parts.length != 3 || !"Body".equals(parts[1])) {
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 01b994cc13..69fe963b5e 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -124,6 +124,12 @@
          ensure that the end of stream flag is set on the headers frame and 
that
          no data frame is sent. (markt)
        </fix>
+      <fix>
+        <bug>66455</bug>: Fix the cause of a potential
+        <code>ClassCastException</code> when processing a
+        <code>WINDOW_UPDATE</code> frame on an HTTP/2 connection where the flow
+        control window for the overall connection has been exhausted. (markt)
+      </fix>
      </changelog>
    </subsection>
    <subsection name="Jasper">


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to