connection.go | 6 +++--- connection_test.go | 17 ++++++++++++++--- torrent.go | 3 +++ diff --git a/connection.go b/connection.go index 5493714bdabee9b177b031e1f22ab56088db05ca..fbc888c3fbedf766783d3ee50f61c5d40743a151 100644 --- a/connection.go +++ b/connection.go @@ -942,15 +942,15 @@ } else { unexpectedChunksReceived.Add(1) } - index := int(req.Index) - piece := &t.pieces[index] - // Do we actually want this chunk? if !t.wantPiece(req) { unwantedChunksReceived.Add(1) c.UnwantedChunksReceived++ return } + + index := int(req.Index) + piece := &t.pieces[index] c.UsefulChunksReceived++ c.lastUsefulChunkReceived = time.Now() diff --git a/connection_test.go b/connection_test.go index 31ddbe141822f8bb7407e83530e6f43e1c72ead9..48fb4f5f9a447c3cae090e596e7d02c8b29cba53 100644 --- a/connection_test.go +++ b/connection_test.go @@ -16,7 +16,7 @@ "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/anacrolix/torrent/metainfo" - "github.com/anacrolix/torrent/peer_protocol" + pp "github.com/anacrolix/torrent/peer_protocol" "github.com/anacrolix/torrent/storage" ) @@ -157,8 +157,8 @@ mrlErr <- err } close(mrlErr) }() - msg := peer_protocol.Message{ - Type: peer_protocol.Piece, + msg := pp.Message{ + Type: pp.Piece, Piece: make([]byte, defaultChunkSize), } wb, err := msg.MarshalBinary() @@ -178,3 +178,14 @@ w.Close() require.NoError(b, <-mrlErr) require.EqualValues(b, b.N, cn.UsefulChunksReceived) } + +func TestConnectionReceiveBadChunkIndex(t *testing.T) { + cn := connection{ + t: &Torrent{}, + } + require.False(t, cn.t.haveInfo()) + assert.NotPanics(t, func() { cn.receiveChunk(&pp.Message{}) }) + cn.t.info = &metainfo.Info{} + require.True(t, cn.t.haveInfo()) + assert.NotPanics(t, func() { cn.receiveChunk(&pp.Message{}) }) +} diff --git a/torrent.go b/torrent.go index d0f81fd7f1bc3a2628ca5abd3616b0d486b74e1e..2577960ca3eea6bf6cd5c78778c4c2e7b35a12b7 100644 --- a/torrent.go +++ b/torrent.go @@ -734,6 +734,9 @@ func (t *Torrent) wantPieceIndex(index int) bool { if !t.haveInfo() { return false } + if index < 0 || index >= t.numPieces() { + return false + } p := &t.pieces[index] if p.QueuedForHash { return false