github.com/anacrolix/torrent@v1.61.0/storage/safe-path_test.go (about)

     1  package storage
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"log"
     7  	"path/filepath"
     8  	"testing"
     9  
    10  	"github.com/go-quicktest/qt"
    11  
    12  	"github.com/anacrolix/torrent/metainfo"
    13  )
    14  
    15  func init() {
    16  	log.SetFlags(log.Flags() | log.Lshortfile)
    17  }
    18  
    19  // I think these are mainly tests for bad metainfos that try to escape the client base directory.
    20  var safeFilePathTests = []struct {
    21  	input     []string
    22  	expectErr bool
    23  }{
    24  	// We might want a test for invalid chars inside components, or file maker opt funcs returning
    25  	// absolute paths (and thus presumably clobbering earlier "makers").
    26  	{input: []string{"a", filepath.FromSlash(`b/..`)}, expectErr: false},
    27  	{input: []string{"a", filepath.FromSlash(`b/../../..`)}, expectErr: true},
    28  	{input: []string{"a", filepath.FromSlash(`b/../.././..`)}, expectErr: true},
    29  	{
    30  		input: []string{
    31  			filepath.FromSlash(`NewSuperHeroMovie-2019-English-720p.avi /../../../../../Roaming/Microsoft/Windows/Start Menu/Programs/Startup/test3.exe`),
    32  		},
    33  		expectErr: true,
    34  	},
    35  }
    36  
    37  // Tests the ToSafeFilePath func.
    38  func TestToSafeFilePath(t *testing.T) {
    39  	for _, _case := range safeFilePathTests {
    40  		actual, err := ToSafeFilePath(_case.input...)
    41  		if _case.expectErr {
    42  			if err != nil {
    43  				continue
    44  			}
    45  			t.Errorf("%q: expected error, got output %q", _case.input, actual)
    46  		}
    47  	}
    48  }
    49  
    50  // Check that safe file path handling still exists for the newer file-opt-maker variants.
    51  func TestFileOptsSafeFilePathHandling(t *testing.T) {
    52  	for i, _case := range safeFilePathTests {
    53  		t.Run(fmt.Sprintf("Case%v", i), func(t *testing.T) {
    54  			info := metainfo.Info{
    55  				Files: []metainfo.FileInfo{
    56  					{Path: _case.input},
    57  				},
    58  			}
    59  			client := NewFileOpts(NewFileClientOpts{
    60  				ClientBaseDir: t.TempDir(),
    61  			})
    62  			defer func() { qt.Assert(t, qt.IsNil(client.Close())) }()
    63  			torImpl, err := client.OpenTorrent(context.Background(), &info, metainfo.Hash{})
    64  			if _case.expectErr {
    65  				qt.Check(t, qt.Not(qt.IsNil(err)))
    66  			} else {
    67  				qt.Check(t, qt.IsNil(torImpl.Close()))
    68  			}
    69  		})
    70  	}
    71  }