[System] Fix bug #31209 - HttpConnection infinite loop
authorAdam Burgess <AdamBurgess@users.noreply.github.com>
Fri, 2 Oct 2015 14:06:08 +0000 (14:06 +0000)
committerAdam Burgess <AdamBurgess@users.noreply.github.com>
Fri, 2 Oct 2015 14:11:11 +0000 (14:11 +0000)
A continue statement in a do...while loop was skipping code to read the next line in a connection, causing an infinite loop.
Fixed by refactoring the loop, removing duplicated code.

mcs/class/System/System.Net/HttpConnection.cs
mcs/class/System/Test/System.Net/HttpListener2Test.cs

index 263bfcd65f78ebb748764e7e9718ae6a2a65b7c4..066a4167a8fc5510ba9cee957cb8724442fbe364 100644 (file)
@@ -306,18 +306,25 @@ namespace System.Net {
                        int used = 0;
                        string line;
 
-                       try {
-                               line = ReadLine (buffer, position, len - position, ref used);
-                               position += used;
-                       } catch {
-                               context.ErrorMessage = "Bad request";
-                               context.ErrorStatus = 400;
-                               return true;
-                       }
+                       while (true) {
+                               if (context.HaveError)
+                                       return true;
+
+                               if (position >= len)
+                                       break;
+
+                               try {
+                                       line = ReadLine (buffer, position, len - position, ref used);
+                                       position += used;
+                               } catch {
+                                       context.ErrorMessage = "Bad request";
+                                       context.ErrorStatus = 400;
+                                       return true;
+                               }
 
-                       do {
                                if (line == null)
                                        break;
+
                                if (line == "") {
                                        if (input_state == InputState.RequestLine)
                                                continue;
@@ -338,21 +345,7 @@ namespace System.Net {
                                                return true;
                                        }
                                }
-
-                               if (context.HaveError)
-                                       return true;
-
-                               if (position >= len)
-                                       break;
-                               try {
-                                       line = ReadLine (buffer, position, len - position, ref used);
-                                       position += used;
-                               } catch {
-                                       context.ErrorMessage = "Bad request";
-                                       context.ErrorStatus = 400;
-                                       return true;
-                               }
-                       } while (line != null);
+                       }
 
                        if (used == len) {
                                ms.SetLength (0);
index 822bced92518cc7066b3ea109dd0b391c5db27df..ab2901624e48fbb2e754d53d046ceb1fdadd0f3d 100644 (file)
@@ -774,5 +774,23 @@ namespace MonoTests.System.Net {
                        var c = new TcpClient ("localhost", port);
                        h.Stop ();
                }
+
+               // Test case for bug #31209
+               [Test]
+               public void Test_EmptyLineAtStart ()
+               {
+                       var listener = HttpListener2Test.CreateAndStartListener ("http://127.0.0.1:9124/");
+                       var ns = HttpListener2Test.CreateNS (9124);
+
+                       HttpListener2Test.Send (ns, "\r\nGET / HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n");
+
+                       bool timedout;
+                       HttpListener2Test.GetContextWithTimeout (listener, 1000, out timedout);
+
+                       Assert.IsFalse (timedout, "timed out");
+
+                       ns.Close ();
+                       listener.Close ();
+               }
        }
 }