]> Cypherpunks repositories - gostls13.git/commitdiff
encoding/json: do not read beyond array literal
authorRuss Cox <rsc@golang.org>
Tue, 18 Sep 2012 18:22:55 +0000 (14:22 -0400)
committerRuss Cox <rsc@golang.org>
Tue, 18 Sep 2012 18:22:55 +0000 (14:22 -0400)
Fixes #3942.

R=golang-dev, mike.rosset, r
CC=golang-dev
https://golang.org/cl/6524043

src/pkg/encoding/json/stream.go
src/pkg/encoding/json/stream_test.go

index 5c196faeab00d1f22be59aeebee51db6efe13ad1..9592467d25baaefa853bdc2f1c87751b8fe4564f 100644 (file)
@@ -78,7 +78,7 @@ Input:
                        // scanEnd is delayed one byte.
                        // We might block trying to get that byte from src,
                        // so instead invent a space byte.
-                       if v == scanEndObject && dec.scan.step(&dec.scan, ' ') == scanEnd {
+                       if (v == scanEndObject || v == scanEndArray) && dec.scan.step(&dec.scan, ' ') == scanEnd {
                                scanp += i + 1
                                break Input
                        }
index ce5a7e6d65625ea52b0d5c340833eb30e83d5372..4d66f556767215d8abd4e88d6b161d8caf85efac 100644 (file)
@@ -6,6 +6,7 @@ package json
 
 import (
        "bytes"
+       "net"
        "reflect"
        "testing"
 )
@@ -145,3 +146,24 @@ func TestNullRawMessage(t *testing.T) {
                t.Fatalf("Marshal: have %#q want %#q", b, msg)
        }
 }
+
+var blockingTests = []string{
+       `{"x": 1}`,
+       `[1, 2, 3]`,
+}
+
+func TestBlocking(t *testing.T) {
+       for _, enc := range blockingTests {
+               r, w := net.Pipe()
+               go w.Write([]byte(enc))
+               var val interface{}
+
+               // If Decode reads beyond what w.Write writes above,
+               // it will block, and the test will deadlock.
+               if err := NewDecoder(r).Decode(&val); err != nil {
+                       t.Errorf("decoding %s: %v", enc, err)
+               }
+               r.Close()
+               w.Close()
+       }
+}