2020-10-15 12:45:08 +08:00
|
|
|
package storage
|
|
|
|
|
|
|
|
import (
|
2021-09-02 08:21:46 +08:00
|
|
|
"fmt"
|
2020-10-15 12:45:08 +08:00
|
|
|
"log"
|
|
|
|
"path/filepath"
|
|
|
|
"testing"
|
2021-09-02 08:21:46 +08:00
|
|
|
|
|
|
|
"github.com/anacrolix/torrent/metainfo"
|
|
|
|
qt "github.com/frankban/quicktest"
|
2020-10-15 12:45:08 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
log.SetFlags(log.Flags() | log.Lshortfile)
|
|
|
|
}
|
|
|
|
|
2021-09-02 08:21:46 +08:00
|
|
|
// I think these are mainly tests for bad metainfos that try to escape the client base directory.
|
|
|
|
var safeFilePathTests = []struct {
|
|
|
|
input []string
|
|
|
|
expectErr bool
|
|
|
|
}{
|
|
|
|
// We might want a test for invalid chars inside components, or file maker opt funcs returning
|
|
|
|
// absolute paths (and thus presumably clobbering earlier "makers").
|
|
|
|
{input: []string{"a", filepath.FromSlash(`b/..`)}, expectErr: false},
|
|
|
|
{input: []string{"a", filepath.FromSlash(`b/../../..`)}, expectErr: true},
|
|
|
|
{input: []string{"a", filepath.FromSlash(`b/../.././..`)}, expectErr: true},
|
|
|
|
{input: []string{
|
|
|
|
filepath.FromSlash(`NewSuperHeroMovie-2019-English-720p.avi /../../../../../Roaming/Microsoft/Windows/Start Menu/Programs/Startup/test3.exe`)},
|
|
|
|
expectErr: true,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
// Tests the ToSafeFilePath func.
|
|
|
|
func TestToSafeFilePath(t *testing.T) {
|
|
|
|
for _, _case := range safeFilePathTests {
|
2020-10-15 12:45:08 +08:00
|
|
|
actual, err := ToSafeFilePath(_case.input...)
|
|
|
|
if _case.expectErr {
|
|
|
|
if err != nil {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
t.Errorf("%q: expected error, got output %q", _case.input, actual)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-09-02 08:21:46 +08:00
|
|
|
|
|
|
|
// Check that safe file path handling still exists for the newer file-opt-maker variants.
|
|
|
|
func TestFileOptsSafeFilePathHandling(t *testing.T) {
|
|
|
|
c := qt.New(t)
|
|
|
|
for i, _case := range safeFilePathTests {
|
|
|
|
c.Run(fmt.Sprintf("Case%v", i), func(c *qt.C) {
|
|
|
|
info := metainfo.Info{
|
|
|
|
Files: []metainfo.FileInfo{
|
|
|
|
{Path: _case.input},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
client := NewFileOpts(NewFileClientOpts{
|
2021-09-09 10:58:07 +08:00
|
|
|
ClientBaseDir: t.TempDir(),
|
2021-09-02 08:21:46 +08:00
|
|
|
})
|
|
|
|
defer func() { c.Check(client.Close(), qt.IsNil) }()
|
|
|
|
torImpl, err := client.OpenTorrent(&info, metainfo.Hash{})
|
|
|
|
if _case.expectErr {
|
|
|
|
c.Check(err, qt.Not(qt.IsNil))
|
|
|
|
} else {
|
|
|
|
c.Check(torImpl.Close(), qt.IsNil)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|