mirror of
https://github.com/restic/restic.git
synced 2025-07-28 09:13:36 +00:00
fs/reader: return proper error on invalid filename
This commit is contained in:
parent
ddd48f1e98
commit
9f39e8a1d3
@ -591,10 +591,13 @@ func runBackup(ctx context.Context, opts BackupOptions, gopts GlobalOptions, ter
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
targetFS = fs.NewReader(filename, source, fs.ReaderOptions{
|
targetFS, err = fs.NewReader(filename, source, fs.ReaderOptions{
|
||||||
ModTime: timeStamp,
|
ModTime: timeStamp,
|
||||||
Mode: 0644,
|
Mode: 0644,
|
||||||
})
|
})
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to backup from stdin: %w", err)
|
||||||
|
}
|
||||||
targets = []string{filename}
|
targets = []string{filename}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,10 +174,11 @@ func TestArchiverSaveFileReaderFS(t *testing.T) {
|
|||||||
|
|
||||||
ts := time.Now()
|
ts := time.Now()
|
||||||
filename := "xx"
|
filename := "xx"
|
||||||
readerFs := fs.NewReader(filename, io.NopCloser(strings.NewReader(test.Data)), fs.ReaderOptions{
|
readerFs, err := fs.NewReader(filename, io.NopCloser(strings.NewReader(test.Data)), fs.ReaderOptions{
|
||||||
ModTime: ts,
|
ModTime: ts,
|
||||||
Mode: 0123,
|
Mode: 0123,
|
||||||
})
|
})
|
||||||
|
rtest.OK(t, err)
|
||||||
|
|
||||||
node, stats := saveFile(t, repo, filename, readerFs)
|
node, stats := saveFile(t, repo, filename, readerFs)
|
||||||
|
|
||||||
@ -286,11 +287,11 @@ func TestArchiverSaveReaderFS(t *testing.T) {
|
|||||||
|
|
||||||
ts := time.Now()
|
ts := time.Now()
|
||||||
filename := "xx"
|
filename := "xx"
|
||||||
readerFs := fs.NewReader(filename, io.NopCloser(strings.NewReader(test.Data)), fs.ReaderOptions{
|
readerFs, err := fs.NewReader(filename, io.NopCloser(strings.NewReader(test.Data)), fs.ReaderOptions{
|
||||||
ModTime: ts,
|
ModTime: ts,
|
||||||
Mode: 0123,
|
Mode: 0123,
|
||||||
})
|
})
|
||||||
|
rtest.OK(t, err)
|
||||||
arch := New(repo, readerFs, Options{})
|
arch := New(repo, readerFs, Options{})
|
||||||
arch.Error = func(item string, err error) error {
|
arch.Error = func(item string, err error) error {
|
||||||
t.Errorf("archiver error for %v: %v", item, err)
|
t.Errorf("archiver error for %v: %v", item, err)
|
||||||
|
@ -42,9 +42,12 @@ type readerItem struct {
|
|||||||
// statically ensure that Local implements FS.
|
// statically ensure that Local implements FS.
|
||||||
var _ FS = &Reader{}
|
var _ FS = &Reader{}
|
||||||
|
|
||||||
func NewReader(name string, r io.ReadCloser, opts ReaderOptions) *Reader {
|
func NewReader(name string, r io.ReadCloser, opts ReaderOptions) (*Reader, error) {
|
||||||
items := make(map[string]readerItem)
|
items := make(map[string]readerItem)
|
||||||
name = readerCleanPath(name)
|
name = readerCleanPath(name)
|
||||||
|
if name == "/" {
|
||||||
|
return nil, fmt.Errorf("invalid filename specified")
|
||||||
|
}
|
||||||
|
|
||||||
isFile := true
|
isFile := true
|
||||||
for {
|
for {
|
||||||
@ -89,7 +92,7 @@ func NewReader(name string, r io.ReadCloser, opts ReaderOptions) *Reader {
|
|||||||
}
|
}
|
||||||
return &Reader{
|
return &Reader{
|
||||||
items: items,
|
items: items,
|
||||||
}
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func readerCleanPath(name string) string {
|
func readerCleanPath(name string) string {
|
||||||
|
@ -185,15 +185,16 @@ func TestFSReader(t *testing.T) {
|
|||||||
tests = append(tests, createFileTest(filename, now, data)...)
|
tests = append(tests, createFileTest(filename, now, data)...)
|
||||||
tests = append(tests, createDirTest("", now)...)
|
tests = append(tests, createDirTest("", now)...)
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, tst := range tests {
|
||||||
fs := NewReader(filename, io.NopCloser(bytes.NewReader(data)), ReaderOptions{
|
fs, err := NewReader(filename, io.NopCloser(bytes.NewReader(data)), ReaderOptions{
|
||||||
Mode: 0644,
|
Mode: 0644,
|
||||||
Size: int64(len(data)),
|
Size: int64(len(data)),
|
||||||
ModTime: now,
|
ModTime: now,
|
||||||
})
|
})
|
||||||
|
test.OK(t, err)
|
||||||
|
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(tst.name, func(t *testing.T) {
|
||||||
test.f(t, fs)
|
tst.f(t, fs)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -211,15 +212,16 @@ func TestFSReaderNested(t *testing.T) {
|
|||||||
tests = append(tests, createDirTest("foo", now)...)
|
tests = append(tests, createDirTest("foo", now)...)
|
||||||
tests = append(tests, createDirTest("foo/sub", now)...)
|
tests = append(tests, createDirTest("foo/sub", now)...)
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, tst := range tests {
|
||||||
fs := NewReader(filename, io.NopCloser(bytes.NewReader(data)), ReaderOptions{
|
fs, err := NewReader(filename, io.NopCloser(bytes.NewReader(data)), ReaderOptions{
|
||||||
Mode: 0644,
|
Mode: 0644,
|
||||||
Size: int64(len(data)),
|
Size: int64(len(data)),
|
||||||
ModTime: now,
|
ModTime: now,
|
||||||
})
|
})
|
||||||
|
test.OK(t, err)
|
||||||
|
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(tst.name, func(t *testing.T) {
|
||||||
test.f(t, fs)
|
tst.f(t, fs)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -244,12 +246,12 @@ func TestFSReaderDir(t *testing.T) {
|
|||||||
|
|
||||||
for _, tst := range tests {
|
for _, tst := range tests {
|
||||||
t.Run(tst.name, func(t *testing.T) {
|
t.Run(tst.name, func(t *testing.T) {
|
||||||
fs := NewReader(tst.filename, io.NopCloser(bytes.NewReader(data)), ReaderOptions{
|
fs, err := NewReader(tst.filename, io.NopCloser(bytes.NewReader(data)), ReaderOptions{
|
||||||
Mode: 0644,
|
Mode: 0644,
|
||||||
Size: int64(len(data)),
|
Size: int64(len(data)),
|
||||||
ModTime: now,
|
ModTime: now,
|
||||||
})
|
})
|
||||||
|
test.OK(t, err)
|
||||||
dir := path.Dir(tst.filename)
|
dir := path.Dir(tst.filename)
|
||||||
for {
|
for {
|
||||||
if dir == "/" || dir == "." {
|
if dir == "/" || dir == "." {
|
||||||
@ -294,12 +296,12 @@ func TestFSReaderMinFileSize(t *testing.T) {
|
|||||||
|
|
||||||
for _, tst := range tests {
|
for _, tst := range tests {
|
||||||
t.Run(tst.name, func(t *testing.T) {
|
t.Run(tst.name, func(t *testing.T) {
|
||||||
fs := NewReader("testfile", io.NopCloser(strings.NewReader(tst.data)), ReaderOptions{
|
fs, err := NewReader("testfile", io.NopCloser(strings.NewReader(tst.data)), ReaderOptions{
|
||||||
Mode: 0644,
|
Mode: 0644,
|
||||||
ModTime: time.Now(),
|
ModTime: time.Now(),
|
||||||
AllowEmptyFile: tst.allowEmpty,
|
AllowEmptyFile: tst.allowEmpty,
|
||||||
})
|
})
|
||||||
|
test.OK(t, err)
|
||||||
f, err := fs.OpenFile("testfile", O_RDONLY, false)
|
f, err := fs.OpenFile("testfile", O_RDONLY, false)
|
||||||
test.OK(t, err)
|
test.OK(t, err)
|
||||||
|
|
||||||
|
@ -908,11 +908,12 @@ func TestRestorerSparseFiles(t *testing.T) {
|
|||||||
|
|
||||||
var zeros [1<<20 + 13]byte
|
var zeros [1<<20 + 13]byte
|
||||||
|
|
||||||
target := fs.NewReader("/zeros", io.NopCloser(bytes.NewReader(zeros[:])), fs.ReaderOptions{
|
target, err := fs.NewReader("/zeros", io.NopCloser(bytes.NewReader(zeros[:])), fs.ReaderOptions{
|
||||||
Mode: 0600,
|
Mode: 0600,
|
||||||
})
|
})
|
||||||
|
rtest.OK(t, err)
|
||||||
sc := archiver.NewScanner(target)
|
sc := archiver.NewScanner(target)
|
||||||
err := sc.Scan(context.TODO(), []string{"/zeros"})
|
err = sc.Scan(context.TODO(), []string{"/zeros"})
|
||||||
rtest.OK(t, err)
|
rtest.OK(t, err)
|
||||||
|
|
||||||
arch := archiver.New(repo, target, archiver.Options{})
|
arch := archiver.New(repo, target, archiver.Options{})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user