]> Sergey Matveev's repositories - btrtrc.git/commitdiff
bencode: Enforce dict key ordering
authorMatt Joiner <anacrolix@gmail.com>
Fri, 10 Dec 2021 03:05:00 +0000 (14:05 +1100)
committerMatt Joiner <anacrolix@gmail.com>
Sun, 12 Dec 2021 05:56:01 +0000 (16:56 +1100)
Fix bencode dict key ordering in HTTP tracker test

bencode/decode.go
bencode/decode_test.go
bencode/testdata/fuzz/FuzzInterfaceRoundTrip/b83176c6cec6b92f5c66774ae105efbc87c9aee44b9a55dba7f1789d8d862f45 [new file with mode: 0644]
tracker/http/http_test.go

index 31ce157fece95b9d505dfdf64bb5bf6375351e41..90397854bcd0bc1bdb7f66e79145fdad149dd81f 100644 (file)
@@ -652,7 +652,9 @@ func (d *Decoder) parseStringInterface() string {
 
 func (d *Decoder) parseDictInterface() interface{} {
        dict := make(map[string]interface{})
+       lastKey := ""
        for {
+               start := d.Offset
                keyi, ok := d.parseValueInterface()
                if !ok {
                        break
@@ -665,12 +667,16 @@ func (d *Decoder) parseDictInterface() interface{} {
                                What:   errors.New("non-string key in a dict"),
                        })
                }
-
+               if key <= lastKey {
+                       d.throwSyntaxError(start, fmt.Errorf("dict keys unsorted: %q <= %q", key, lastKey))
+               }
+               start = d.Offset
                valuei, ok := d.parseValueInterface()
                if !ok {
-                       break
+                       d.throwSyntaxError(start, fmt.Errorf("dict elem missing value [key=%v]", key))
                }
 
+               lastKey = key
                dict[key] = valuei
        }
        return dict
index 60541e86d096bc66ae9fc414f0dff81b4867f9d9..461b3690862743214c32c3bfd2d0254ac4cb5fde 100644 (file)
@@ -33,8 +33,8 @@ var random_decode_tests = []random_decode_test{
                ret, _ := big.NewInt(-1).SetString("604919719469385652980544193299329427705624352086", 10)
                return ret
        }()},
-       {"d1:rd6:\xd4/\xe2F\x00\x01e1:t3:\x9a\x87\x011:v4:TR%=1:y1:re", map[string]interface{}{
-               "r": map[string]interface{}{},
+       {"d1:rd6:\xd4/\xe2F\x00\x01i42ee1:t3:\x9a\x87\x011:v4:TR%=1:y1:re", map[string]interface{}{
+               "r": map[string]interface{}{"\xd4/\xe2F\x00\x01": int64(42)},
                "t": "\x9a\x87\x01",
                "v": "TR%=",
                "y": "r",
diff --git a/bencode/testdata/fuzz/FuzzInterfaceRoundTrip/b83176c6cec6b92f5c66774ae105efbc87c9aee44b9a55dba7f1789d8d862f45 b/bencode/testdata/fuzz/FuzzInterfaceRoundTrip/b83176c6cec6b92f5c66774ae105efbc87c9aee44b9a55dba7f1789d8d862f45
new file mode 100644 (file)
index 0000000..60cc554
--- /dev/null
@@ -0,0 +1,2 @@
+go test fuzz v1
+[]byte("d3:A005:000003:000i0ee")
index fce77c05e10e242b276df4721497d9f368e4040f..908b14126124affa81f229869b035e1eb7739341 100644 (file)
@@ -16,7 +16,7 @@ func TestUnmarshalHTTPResponsePeerDicts(t *testing.T) {
        require.NoError(t, bencode.Unmarshal(
                []byte("d5:peersl"+
                        "d2:ip7:1.2.3.47:peer id20:thisisthe20bytepeeri4:porti9999ee"+
-                       "d7:peer id20:thisisthe20bytepeeri2:ip39:2001:0db8:85a3:0000:0000:8a2e:0370:73344:porti9998ee"+
+                       "d2:ip39:2001:0db8:85a3:0000:0000:8a2e:0370:73347:peer id20:thisisthe20bytepeeri4:porti9998ee"+
                        "e"+
                        "6:peers618:123412341234123456"+
                        "e"),