Author: markt
Date: Thu Nov 16 10:14:39 2017
New Revision: 1815429

URL: http://svn.apache.org/viewvc?rev=1815429&view=rev
Log:
Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=61682
When re-prioritising HTTP/2 streams, ensure that both parent and children 
fields are correctly updated to avoid a possible StackOverflowError

Modified:
    tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java
    tomcat/trunk/java/org/apache/coyote/http2/Stream.java
    tomcat/trunk/test/org/apache/coyote/http2/TestAbstractStream.java
    tomcat/trunk/webapps/docs/changelog.xml

Modified: tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java?rev=1815429&r1=1815428&r2=1815429&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java 
(original)
+++ tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java Thu Nov 
16 10:14:39 2017
@@ -1108,6 +1108,7 @@ class Http2UpgradeHandler extends Abstra
             }
         }
         streamToRemove.detachFromParent();
+        streamToRemove.getChildStreams().clear();
     }
 
 

Modified: tomcat/trunk/java/org/apache/coyote/http2/Stream.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/Stream.java?rev=1815429&r1=1815428&r2=1815429&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http2/Stream.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http2/Stream.java Thu Nov 16 10:14:39 
2017
@@ -87,7 +87,7 @@ class Stream extends AbstractStream impl
     Stream(Integer identifier, Http2UpgradeHandler handler, Request 
coyoteRequest) {
         super(identifier);
         this.handler = handler;
-        setParentStream(handler);
+        handler.addChild(this);
         setWindowSize(handler.getRemoteSettings().getInitialWindowSize());
         state = new StreamStateMachine(this);
         if (coyoteRequest == null) {
@@ -139,6 +139,7 @@ class Stream extends AbstractStream impl
                 this.addChild(parentsChild);
             }
         }
+        detachFromParent();
         parent.addChild(this);
         this.weight = weight;
     }

Modified: tomcat/trunk/test/org/apache/coyote/http2/TestAbstractStream.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/coyote/http2/TestAbstractStream.java?rev=1815429&r1=1815428&r2=1815429&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/coyote/http2/TestAbstractStream.java (original)
+++ tomcat/trunk/test/org/apache/coyote/http2/TestAbstractStream.java Thu Nov 
16 10:14:39 2017
@@ -243,7 +243,44 @@ public class TestAbstractStream {
         Assert.assertTrue(e.getChildStreams().contains(f));
         Assert.assertEquals(1,  f.getChildStreams().size());
         Assert.assertTrue(f.getChildStreams().contains(a));
-
     }
 
+
+    // https://bz.apache.org/bugzilla/show_bug.cgi?id=61682
+    @Test
+    public void testCircular03() {
+        // Setup
+        Http2UpgradeHandler handler = new Http2UpgradeHandler(new 
Http2Protocol(), null, null);
+        Stream a = new Stream(Integer.valueOf(1), handler);
+        Stream b = new Stream(Integer.valueOf(3), handler);
+        Stream c = new Stream(Integer.valueOf(5), handler);
+        Stream d = new Stream(Integer.valueOf(7), handler);
+
+        // Action
+        b.rePrioritise(a, false, 16);
+        c.rePrioritise(a, false, 16);
+        d.rePrioritise(b, false, 16);
+        c.rePrioritise(handler, false, 16);
+        a.rePrioritise(c, false, 16);
+
+        // Check parents
+        Assert.assertEquals(c, a.getParentStream());
+        Assert.assertEquals(a, b.getParentStream());
+        Assert.assertEquals(handler, c.getParentStream());
+        Assert.assertEquals(b, d.getParentStream());
+
+        // This triggers the StackOverflowError
+        c.isDescendant(d);
+
+        // Check children
+        Assert.assertEquals(1,  handler.getChildStreams().size());
+        Assert.assertTrue(handler.getChildStreams().contains(c));
+        Assert.assertEquals(1,  c.getChildStreams().size());
+        Assert.assertTrue(c.getChildStreams().contains(a));
+        Assert.assertEquals(1,  a.getChildStreams().size());
+        Assert.assertTrue(a.getChildStreams().contains(b));
+        Assert.assertEquals(1,  b.getChildStreams().size());
+        Assert.assertTrue(b.getChildStreams().contains(d));
+        Assert.assertEquals(0,  d.getChildStreams().size());
+    }
 }

Modified: tomcat/trunk/webapps/docs/changelog.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1815429&r1=1815428&r2=1815429&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Thu Nov 16 10:14:39 2017
@@ -68,6 +68,11 @@
         ensure that an HTTP session exists when initiating a WebSocket
         connection. Patch provided by isapir. (markt)
       </add>
+      <fix>
+        <bug>61682</bug>: When re-prioritising HTTP/2 streams, ensure that both
+        parent and children fields are correctly updated to avoid a possible
+        <code>StackOverflowError</code>. (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Coyote">



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

Reply via email to