Fixes #949.
--- /dev/null
+package torrent
+
+import (
+ "github.com/anacrolix/torrent/metainfo"
+ qt "github.com/frankban/quicktest"
+ "testing"
+)
+
+func TestIssue949LastPieceZeroPadding(t *testing.T) {
+ // This torrent has a padding file after the last file listed in the v2 info file tree.
+ mi, err := metainfo.LoadFromFile("testdata/issue-949.torrent")
+ if err != nil {
+ panic(err)
+ }
+ info, err := mi.UnmarshalInfo()
+ if err != nil {
+ panic(err)
+ }
+ lastPiece := info.Piece(info.NumPieces() - 1)
+ c := qt.New(t)
+ c.Assert(info.FilesArePieceAligned(), qt.IsTrue)
+ // Check the v1 piece length includes the trailing padding file.
+ c.Check(lastPiece.V1Length(), qt.Equals, info.PieceLength)
+ // The v2 piece should only include the file data, which fits inside the piece length for this
+ // file.
+ c.Check(lastPiece.Length(), qt.Equals, int64(3677645))
+}
return len(info.Files) != 0
}
-// The files field, converted up from the old single-file in the parent info
-// dict if necessary. This is a helper to avoid having to conditionally handle
-// single and multi-file torrent infos.
+// The files field, converted up from the old single-file in the parent info dict if necessary. This
+// is a helper to avoid having to conditionally handle single and multi-file torrent infos.
func (info *Info) UpvertedFiles() (files []FileInfo) {
if info.HasV2() {
info.FileTree.upvertedFiles(info.PieceLength, func(fi FileInfo) {
})
return
}
+ return info.UpvertedV1Files()
+}
+
+// UpvertedFiles but specific to the files listed in the v1 info fields. This will include padding
+// files for example that wouldn't appear in v2 file trees.
+func (info *Info) UpvertedV1Files() (files []FileInfo) {
if len(info.Files) == 0 {
return []FileInfo{{
Length: info.Length,
case 0 <= i && i < lastPiece:
return p.Info.PieceLength
case lastPiece >= 0 && i == lastPiece:
- files := p.Info.UpvertedFiles()
+ files := p.Info.UpvertedV1Files()
lastFile := files[len(files)-1]
length := lastFile.TorrentOffset + lastFile.Length - int64(i)*p.Info.PieceLength
if length <= 0 || length > p.Info.PieceLength {
}
h := pieceHash.New()
differingPeers, err = t.hashPieceWithSpecificHash(piece, h)
- // For a hybrid torrent, we work with the v2 files, but if we use a v1 hash, we can assume that
- // the pieces are padded with zeroes.
+ // For a hybrid torrent, we work with the v2 files, but if we use a v1 hash, we can assume
+ // that the pieces are padded with zeroes.
if t.info.FilesArePieceAligned() {
paddingLen := p.Info().V1Length() - p.Info().Length()
written, err := io.CopyN(h, zeroReader, paddingLen)