From 8764456d23c767f1ae0c9f72087d56d38af32d07 Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Fri, 10 Dec 2021 14:05:00 +1100 Subject: [PATCH] bencode: Enforce dict key ordering Fix bencode dict key ordering in HTTP tracker test --- bencode/decode.go | 10 ++++++++-- bencode/decode_test.go | 4 ++-- ...92f5c66774ae105efbc87c9aee44b9a55dba7f1789d8d862f45 | 2 ++ tracker/http/http_test.go | 2 +- 4 files changed, 13 insertions(+), 5 deletions(-) create mode 100644 bencode/testdata/fuzz/FuzzInterfaceRoundTrip/b83176c6cec6b92f5c66774ae105efbc87c9aee44b9a55dba7f1789d8d862f45 diff --git a/bencode/decode.go b/bencode/decode.go index 31ce157f..90397854 100644 --- a/bencode/decode.go +++ b/bencode/decode.go @@ -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 diff --git a/bencode/decode_test.go b/bencode/decode_test.go index 60541e86..461b3690 100644 --- a/bencode/decode_test.go +++ b/bencode/decode_test.go @@ -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 index 00000000..60cc5540 --- /dev/null +++ b/bencode/testdata/fuzz/FuzzInterfaceRoundTrip/b83176c6cec6b92f5c66774ae105efbc87c9aee44b9a55dba7f1789d8d862f45 @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("d3:A005:000003:000i0ee") diff --git a/tracker/http/http_test.go b/tracker/http/http_test.go index fce77c05..908b1412 100644 --- a/tracker/http/http_test.go +++ b/tracker/http/http_test.go @@ -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"), -- 2.44.0