]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Verify piece layers while adding
authorMatt Joiner <anacrolix@gmail.com>
Wed, 20 Mar 2024 03:03:22 +0000 (14:03 +1100)
committerMatt Joiner <anacrolix@gmail.com>
Wed, 20 Mar 2024 03:03:22 +0000 (14:03 +1100)
client.go
torrent.go

index c70e413320f963a7b0bccfe1cba4bd7771d29540..23decf6ee0b23341b07861ff997370c2c5abb4a8 100644 (file)
--- a/client.go
+++ b/client.go
@@ -1507,7 +1507,7 @@ func (t *Torrent) MergeSpec(spec *TorrentSpec) error {
        t.maybeNewConns()
        t.dataDownloadDisallowed.SetBool(spec.DisallowDataDownload)
        t.dataUploadDisallowed = spec.DisallowDataUpload
-       return t.AddPieceLayers(spec.PieceLayers)
+       return errors.Join(t.AddPieceLayers(spec.PieceLayers)...)
 }
 
 func (cl *Client) dropTorrent(t *Torrent, wg *sync.WaitGroup) (err error) {
index b952e3ce6e13a0b353c85c30a26aecf346a701f2..fe1a19722eb0b1003ff8e1db1ab06b8349ecb8c1 100644 (file)
@@ -425,22 +425,26 @@ func (t *Torrent) makePieces() {
        }
 }
 
-func (t *Torrent) AddPieceLayers(layers map[string]string) (err error) {
+func (t *Torrent) AddPieceLayers(layers map[string]string) (errs []error) {
        if layers == nil {
                return
        }
+files:
        for _, f := range *t.files {
                if !f.piecesRoot.Ok {
-                       err = fmt.Errorf("no piece root set for file %v", f)
-                       return
+                       err := fmt.Errorf("no piece root set for file %v", f)
+                       errs = append(errs, err)
+                       continue files
                }
                compactLayer, ok := layers[string(f.piecesRoot.Value[:])]
                var hashes [][32]byte
                if ok {
+                       var err error
                        hashes, err = merkle.CompactLayerToSliceHashes(compactLayer)
                        if err != nil {
                                err = fmt.Errorf("bad piece layers for file %q: %w", f, err)
-                               return
+                               errs = append(errs, err)
+                               continue files
                        }
                } else if f.length > t.info.PieceLength {
                        // BEP 52 is pretty strongly worded about this, even though we should be able to
@@ -452,8 +456,16 @@ func (t *Torrent) AddPieceLayers(layers map[string]string) (err error) {
                        hashes = [][32]byte{f.piecesRoot.Value}
                }
                if len(hashes) != f.numPieces() {
-                       err = fmt.Errorf("file %q: got %v hashes expected %v", f, len(hashes), f.numPieces())
-                       return
+                       errs = append(
+                               errs,
+                               fmt.Errorf("file %q: got %v hashes expected %v", f, len(hashes), f.numPieces()),
+                       )
+                       continue files
+               }
+               root := merkle.RootWithPadHash(hashes, metainfo.HashForPiecePad(t.info.PieceLength))
+               if root != f.piecesRoot.Value {
+                       errs = append(errs, fmt.Errorf("%v: expected hash %x got %x", f, f.piecesRoot.Value, root))
+                       continue files
                }
                for i := range f.numPieces() {
                        pi := f.BeginPieceIndex() + i
@@ -461,7 +473,7 @@ func (t *Torrent) AddPieceLayers(layers map[string]string) (err error) {
                        p.setV2Hash(hashes[i])
                }
        }
-       return nil
+       return
 }
 
 // Returns the index of the first file containing the piece. files must be