Merge pull request #1481 from restic/add-stdin-path
backup: Reject directories in filename for --stdin
This commit is contained in:
commit
e353b00501
3 changed files with 24 additions and 8 deletions
|
@ -5,6 +5,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -236,10 +237,16 @@ func readBackupFromStdin(opts BackupOptions, gopts GlobalOptions, args []string)
|
||||||
return errors.Fatal("when reading from stdin, no additional files can be specified")
|
return errors.Fatal("when reading from stdin, no additional files can be specified")
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.StdinFilename == "" {
|
fn := opts.StdinFilename
|
||||||
|
|
||||||
|
if fn == "" {
|
||||||
return errors.Fatal("filename for backup from stdin must not be empty")
|
return errors.Fatal("filename for backup from stdin must not be empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if filepath.Base(fn) != fn || path.Base(fn) != fn {
|
||||||
|
return errors.Fatal("filename is invalid (may not contain a directory, slash or backslash)")
|
||||||
|
}
|
||||||
|
|
||||||
if gopts.password == "" {
|
if gopts.password == "" {
|
||||||
return errors.Fatal("unable to read password from stdin when data is to be read from stdin, use --password-file or $RESTIC_PASSWORD")
|
return errors.Fatal("unable to read password from stdin when data is to be read from stdin, use --password-file or $RESTIC_PASSWORD")
|
||||||
}
|
}
|
||||||
|
@ -266,7 +273,7 @@ func readBackupFromStdin(opts BackupOptions, gopts GlobalOptions, args []string)
|
||||||
Hostname: opts.Hostname,
|
Hostname: opts.Hostname,
|
||||||
}
|
}
|
||||||
|
|
||||||
_, id, err := r.Archive(gopts.ctx, opts.StdinFilename, os.Stdin, newArchiveStdinProgress(gopts))
|
_, id, err := r.Archive(gopts.ctx, fn, os.Stdin, newArchiveStdinProgress(gopts))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -388,9 +388,11 @@ func OpenRepository(opts GlobalOptions) (*repository.Repository, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if stdoutIsTerminal() {
|
||||||
Verbosef("found %d old cache directories in %v, pass --cleanup-cache to remove them\n",
|
Verbosef("found %d old cache directories in %v, pass --cleanup-cache to remove them\n",
|
||||||
len(oldCacheDirs), c.Base)
|
len(oldCacheDirs), c.Base)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ package fuse
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
"bazil.org/fuse"
|
"bazil.org/fuse"
|
||||||
"bazil.org/fuse/fs"
|
"bazil.org/fuse/fs"
|
||||||
|
@ -28,6 +29,10 @@ type dir struct {
|
||||||
blobsize *BlobSizeCache
|
blobsize *BlobSizeCache
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func cleanupNodeName(name string) string {
|
||||||
|
return filepath.Base(name)
|
||||||
|
}
|
||||||
|
|
||||||
func newDir(ctx context.Context, root *Root, inode, parentInode uint64, node *restic.Node) (*dir, error) {
|
func newDir(ctx context.Context, root *Root, inode, parentInode uint64, node *restic.Node) (*dir, error) {
|
||||||
debug.Log("new dir for %v (%v)", node.Name, node.Subtree.Str())
|
debug.Log("new dir for %v (%v)", node.Name, node.Subtree.Str())
|
||||||
tree, err := root.repo.LoadTree(ctx, *node.Subtree)
|
tree, err := root.repo.LoadTree(ctx, *node.Subtree)
|
||||||
|
@ -37,7 +42,7 @@ func newDir(ctx context.Context, root *Root, inode, parentInode uint64, node *re
|
||||||
}
|
}
|
||||||
items := make(map[string]*restic.Node)
|
items := make(map[string]*restic.Node)
|
||||||
for _, node := range tree.Nodes {
|
for _, node := range tree.Nodes {
|
||||||
items[node.Name] = node
|
items[cleanupNodeName(node.Name)] = node
|
||||||
}
|
}
|
||||||
|
|
||||||
return &dir{
|
return &dir{
|
||||||
|
@ -84,7 +89,7 @@ func newDirFromSnapshot(ctx context.Context, root *Root, inode uint64, snapshot
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, node := range nodes {
|
for _, node := range nodes {
|
||||||
items[node.Name] = node
|
items[cleanupNodeName(node.Name)] = node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,6 +156,7 @@ func (d *dir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) {
|
||||||
})
|
})
|
||||||
|
|
||||||
for _, node := range d.items {
|
for _, node := range d.items {
|
||||||
|
name := cleanupNodeName(node.Name)
|
||||||
var typ fuse.DirentType
|
var typ fuse.DirentType
|
||||||
switch node.Type {
|
switch node.Type {
|
||||||
case "dir":
|
case "dir":
|
||||||
|
@ -162,9 +168,9 @@ func (d *dir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = append(ret, fuse.Dirent{
|
ret = append(ret, fuse.Dirent{
|
||||||
Inode: fs.GenerateDynamicInode(d.inode, node.Name),
|
Inode: fs.GenerateDynamicInode(d.inode, name),
|
||||||
Type: typ,
|
Type: typ,
|
||||||
Name: node.Name,
|
Name: name,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,6 +182,7 @@ func (d *dir) Lookup(ctx context.Context, name string) (fs.Node, error) {
|
||||||
node, ok := d.items[name]
|
node, ok := d.items[name]
|
||||||
if !ok {
|
if !ok {
|
||||||
debug.Log(" Lookup(%v) -> not found", name)
|
debug.Log(" Lookup(%v) -> not found", name)
|
||||||
|
debug.Log(" items: %v\n", d.items)
|
||||||
return nil, fuse.ENOENT
|
return nil, fuse.ENOENT
|
||||||
}
|
}
|
||||||
switch node.Type {
|
switch node.Type {
|
||||||
|
|
Loading…
Reference in a new issue