From 4ff97dd4d243b514133e502d617bdada44190bca Mon Sep 17 00:00:00 2001 From: Evrins Hu Date: Mon, 18 Mar 2024 11:34:24 +0800 Subject: [PATCH] fix: can not download invalid utf8 name with BestName and BestPath --- cmd/magnet-metainfo/main.go | 2 +- cmd/torrent/metainfo.go | 2 +- cmd/torrent/serve.go | 4 ++-- fs/torrentfs.go | 10 +++++----- fs/torrentfs_test.go | 2 +- internal/cmd/issue-908/main.go | 2 +- internal/testutil/spec.go | 2 +- metainfo/info.go | 4 ++-- metainfo/metainfo_test.go | 4 ++-- spec.go | 2 +- storage/file.go | 6 +++--- storage/mmap.go | 2 +- webseed/request.go | 2 +- 13 files changed, 22 insertions(+), 22 deletions(-) diff --git a/cmd/magnet-metainfo/main.go b/cmd/magnet-metainfo/main.go index 536f7abff3..0e21d94d95 100644 --- a/cmd/magnet-metainfo/main.go +++ b/cmd/magnet-metainfo/main.go @@ -44,7 +44,7 @@ func main() { <-t.GotInfo() mi := t.Metainfo() t.Drop() - f, err := os.Create(t.Info().Name + ".torrent") + f, err := os.Create(t.Info().BestName() + ".torrent") if err != nil { log.Fatalf("error creating torrent metainfo file: %s", err) } diff --git a/cmd/torrent/metainfo.go b/cmd/torrent/metainfo.go index 929cb45dc9..dd9d399c49 100644 --- a/cmd/torrent/metainfo.go +++ b/cmd/torrent/metainfo.go @@ -97,7 +97,7 @@ func pprintMetainfo(metainfo *metainfo.MetaInfo, flags pprintMetainfoFlags) erro return fmt.Errorf("error unmarshalling info: %s", err) } if flags.JustName { - fmt.Printf("%s\n", info.Name) + fmt.Printf("%s\n", info.BestName()) return nil } d := map[string]interface{}{ diff --git a/cmd/torrent/serve.go b/cmd/torrent/serve.go index d37dafafaa..b257f73af7 100644 --- a/cmd/torrent/serve.go +++ b/cmd/torrent/serve.go @@ -45,7 +45,7 @@ func serve() (cmd bargle.Command) { return fmt.Errorf("building info from path %q: %w", filePath, err) } for _, fi := range info.UpvertedFiles() { - log.Printf("added %q", fi.Path) + log.Printf("added %q", fi.BestPath()) } mi := metainfo.MetaInfo{ InfoBytes: bencode.MustMarshal(info), @@ -61,7 +61,7 @@ func serve() (cmd bargle.Command) { Storage: storage.NewFileOpts(storage.NewFileClientOpts{ ClientBaseDir: filePath, FilePathMaker: func(opts storage.FilePathMakerOpts) string { - return filepath.Join(opts.File.Path...) + return filepath.Join(opts.File.BestPath()...) }, TorrentDirMaker: nil, PieceCompletion: pc, diff --git a/fs/torrentfs.go b/fs/torrentfs.go index 1b7b144e78..f011d19ba8 100644 --- a/fs/torrentfs.go +++ b/fs/torrentfs.go @@ -73,16 +73,16 @@ func isSubPath(parent, child string) bool { func (dn dirNode) ReadDirAll(ctx context.Context) (des []fuse.Dirent, err error) { names := map[string]bool{} for _, fi := range dn.metadata.UpvertedFiles() { - filePathname := strings.Join(fi.Path, "/") + filePathname := strings.Join(fi.BestPath(), "/") if !isSubPath(dn.path, filePathname) { continue } var name string if dn.path == "" { - name = fi.Path[0] + name = fi.BestPath()[0] } else { dirPathname := strings.Split(dn.path, "/") - name = fi.Path[len(dirPathname)] + name = fi.BestPath()[len(dirPathname)] } if names[name] { continue @@ -91,7 +91,7 @@ func (dn dirNode) ReadDirAll(ctx context.Context) (des []fuse.Dirent, err error) de := fuse.Dirent{ Name: name, } - if len(fi.Path) == len(dn.path)+1 { + if len(fi.BestPath()) == len(dn.path)+1 { de.Type = fuse.DT_File } else { de.Type = fuse.DT_Dir @@ -168,7 +168,7 @@ func (rn rootNode) ReadDirAll(ctx context.Context) (dirents []fuse.Dirent, err e continue } dirents = append(dirents, fuse.Dirent{ - Name: info.Name, + Name: info.BestName(), Type: func() fuse.DirentType { if !info.IsDir() { return fuse.DT_File diff --git a/fs/torrentfs_test.go b/fs/torrentfs_test.go index 097f1bb237..1bf9004e61 100644 --- a/fs/torrentfs_test.go +++ b/fs/torrentfs_test.go @@ -130,7 +130,7 @@ func TestUnmountWedged(t *testing.T) { }() go func() { defer cancel() - _, err := ioutil.ReadFile(filepath.Join(layout.MountDir, tt.Info().Name)) + _, err := ioutil.ReadFile(filepath.Join(layout.MountDir, tt.Info().BestName())) require.Error(t, err) }() diff --git a/internal/cmd/issue-908/main.go b/internal/cmd/issue-908/main.go index 96da2e8ebf..1bd59724c7 100644 --- a/internal/cmd/issue-908/main.go +++ b/internal/cmd/issue-908/main.go @@ -49,7 +49,7 @@ func main() { log.Fatal(err) } for _, fi := range info.Files { - log.Printf("added %q", fi.Path) + log.Printf("added %q", fi.BestPath()) } mi := &metainfo.MetaInfo{ InfoBytes: bencode.MustMarshal(info), diff --git a/internal/testutil/spec.go b/internal/testutil/spec.go index 63e4a74c63..ad0e4074de 100644 --- a/internal/testutil/spec.go +++ b/internal/testutil/spec.go @@ -52,7 +52,7 @@ func (t *Torrent) Info(pieceLength int64) metainfo.Info { } } err := info.GeneratePieces(func(fi metainfo.FileInfo) (io.ReadCloser, error) { - return io.NopCloser(strings.NewReader(t.GetFile(strings.Join(fi.Path, "/")).Data)), nil + return io.NopCloser(strings.NewReader(t.GetFile(strings.Join(fi.BestPath(), "/")).Data)), nil }) expect.Nil(err) return info diff --git a/metainfo/info.go b/metainfo/info.go index 5d6300ec51..3f14b08b5b 100644 --- a/metainfo/info.go +++ b/metainfo/info.go @@ -77,13 +77,13 @@ func (info *Info) BuildFromFilePath(root string) (err error) { return } slices.Sort(info.Files, func(l, r FileInfo) bool { - return strings.Join(l.Path, "/") < strings.Join(r.Path, "/") + return strings.Join(l.BestPath(), "/") < strings.Join(r.BestPath(), "/") }) if info.PieceLength == 0 { info.PieceLength = ChoosePieceLength(info.TotalLength()) } err = info.GeneratePieces(func(fi FileInfo) (io.ReadCloser, error) { - return os.Open(filepath.Join(root, strings.Join(fi.Path, string(filepath.Separator)))) + return os.Open(filepath.Join(root, strings.Join(fi.BestPath(), string(filepath.Separator)))) }) if err != nil { err = fmt.Errorf("error generating pieces: %s", err) diff --git a/metainfo/metainfo_test.go b/metainfo/metainfo_test.go index 9f0f9f5f73..4d7c2b343b 100644 --- a/metainfo/metainfo_test.go +++ b/metainfo/metainfo_test.go @@ -24,9 +24,9 @@ func testFile(t *testing.T, filename string) { require.NoError(t, err) if len(info.Files) == 1 { - t.Logf("Single file: %s (length: %d)\n", info.Name, info.Files[0].Length) + t.Logf("Single file: %s (length: %d)\n", info.BestName(), info.Files[0].Length) } else { - t.Logf("Multiple files: %s\n", info.Name) + t.Logf("Multiple files: %s\n", info.BestName()) for _, f := range info.Files { t.Logf(" - %s (length: %d)\n", path.Join(f.Path...), f.Length) } diff --git a/spec.go b/spec.go index f54b325b5c..d0535a99e1 100644 --- a/spec.go +++ b/spec.go @@ -86,7 +86,7 @@ func TorrentSpecFromMetaInfoErr(mi *metainfo.MetaInfo) (*TorrentSpec, error) { InfoHashV2: v2Infohash, PieceLayers: mi.PieceLayers, InfoBytes: mi.InfoBytes, - DisplayName: info.Name, + DisplayName: info.BestName(), Webseeds: mi.UrlList, DhtNodes: func() (ret []string) { ret = make([]string, 0, len(mi.Nodes)) diff --git a/storage/file.go b/storage/file.go index 231825fdfe..d15e579d7e 100644 --- a/storage/file.go +++ b/storage/file.go @@ -39,10 +39,10 @@ func NewFileOpts(opts NewFileClientOpts) ClientImplCloser { if opts.FilePathMaker == nil { opts.FilePathMaker = func(opts FilePathMakerOpts) string { var parts []string - if opts.Info.Name != metainfo.NoName { - parts = append(parts, opts.Info.Name) + if opts.Info.BestName() != metainfo.NoName { + parts = append(parts, opts.Info.BestName()) } - return filepath.Join(append(parts, opts.File.Path...)...) + return filepath.Join(append(parts, opts.File.BestPath()...)...) } } if opts.PieceCompletion == nil { diff --git a/storage/mmap.go b/storage/mmap.go index 1851c3238d..f7536591fa 100644 --- a/storage/mmap.go +++ b/storage/mmap.go @@ -119,7 +119,7 @@ func mMapTorrent(md *metainfo.Info, location string) (mms *mmap_span.MMapSpan, e }() for _, miFile := range md.UpvertedFiles() { var safeName string - safeName, err = ToSafeFilePath(append([]string{md.Name}, miFile.Path...)...) + safeName, err = ToSafeFilePath(append([]string{md.BestName()}, miFile.BestPath()...)...) if err != nil { return } diff --git a/webseed/request.go b/webseed/request.go index a8aefab3b3..63b2166525 100644 --- a/webseed/request.go +++ b/webseed/request.go @@ -57,7 +57,7 @@ func newRequest( if strings.HasSuffix(url_, "/") { // BEP specifies that we append the file path. We need to escape each component of the path // for things like spaces and '#'. - url_ += trailingPath(info.Name, fileInfo.Path, pathEscaper) + url_ += trailingPath(info.BestName(), fileInfo.BestPath(), pathEscaper) } req, err := http.NewRequestWithContext(ctx, http.MethodGet, url_, nil) if err != nil {