Browse Source

http2: correct overflow protection

Correct overflow detection when going negative.

Updates golang/go#25023

Change-Id: Ic2ddb7ee757f081d1826bfbbfd884e2b7e819335
Reviewed-on: https://go-review.googlesource.com/111675
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Michael Fraenkel 7 years ago
parent
commit
d1d521f688
2 changed files with 39 additions and 5 deletions
  1. 5 5
      http2/flow.go
  2. 34 0
      http2/flow_test.go

+ 5 - 5
http2/flow.go

@@ -41,10 +41,10 @@ func (f *flow) take(n int32) {
 // add adds n bytes (positive or negative) to the flow control window.
 // It returns false if the sum would exceed 2^31-1.
 func (f *flow) add(n int32) bool {
-	remain := (1<<31 - 1) - f.n
-	if n > remain {
-		return false
+	sum := f.n + n
+	if (sum > n) == (f.n > 0) {
+		f.n = sum
+		return true
 	}
-	f.n += n
-	return true
+	return false
 }

+ 34 - 0
http2/flow_test.go

@@ -49,5 +49,39 @@ func TestFlowAdd(t *testing.T) {
 	if f.add(1) {
 		t.Fatal("adding 1 to max shouldn't be allowed")
 	}
+}
+
+func TestFlowAddOverflow(t *testing.T) {
+	var f flow
+	if !f.add(0) {
+		t.Fatal("failed to add 0")
+	}
+	if !f.add(-1) {
+		t.Fatal("failed to add -1")
+	}
+	if !f.add(0) {
+		t.Fatal("failed to add 0")
+	}
+	if !f.add(1) {
+		t.Fatal("failed to add 1")
+	}
+	if !f.add(1) {
+		t.Fatal("failed to add 1")
+	}
+	if !f.add(0) {
+		t.Fatal("failed to add 0")
+	}
+	if !f.add(-3) {
+		t.Fatal("failed to add -3")
+	}
+	if got, want := f.available(), int32(-2); got != want {
+		t.Fatalf("size = %d; want %d", got, want)
+	}
+	if !f.add(1<<31 - 1) {
+		t.Fatal("failed to add 2^31-1")
+	}
+	if got, want := f.available(), int32(1+-3+(1<<31-1)); got != want {
+		t.Fatalf("size = %d; want %d", got, want)
+	}
 
 }