mirror of
https://github.com/ipfs/kubo.git
synced 2025-06-28 00:39:31 +08:00
Add path validation in Resolver.ResolvePath
Add ErrNoComponents in ParsePath validation & remove redundant path validation. Any lines using core.Resolve & Resolver.ResolvePath will have their path validated. License: MIT Signed-off-by: rht <rhtbot@gmail.com>
This commit is contained in:
@ -65,14 +65,8 @@ may also specify the level of compression by specifying '-l=<1-9>'.
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate path string
|
p := path.Path(req.Arguments()[0])
|
||||||
p, err := path.ParsePath(req.Arguments()[0])
|
|
||||||
if err != nil {
|
|
||||||
res.SetError(fmt.Errorf("failed to validate path: %v", err), cmds.ErrNormal)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var reader io.Reader
|
var reader io.Reader
|
||||||
|
|
||||||
if archive, _, _ := req.Option("archive").Bool(); !archive && cmplvl != gzip.NoCompression {
|
if archive, _, _ := req.Option("archive").Bool(); !archive && cmplvl != gzip.NoCompression {
|
||||||
// only use this when the flag is '-C' without '-a'
|
// only use this when the flag is '-C' without '-a'
|
||||||
reader, err = getZip(req.Context().Context, node, p, cmplvl)
|
reader, err = getZip(req.Context().Context, node, p, cmplvl)
|
||||||
@ -169,18 +163,18 @@ func getCompressOptions(req cmds.Request) (int, error) {
|
|||||||
return gzip.NoCompression, nil
|
return gzip.NoCompression, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func get(ctx context.Context, node *core.IpfsNode, pathToResolve path.Path, compression int) (io.Reader, error) {
|
func get(ctx context.Context, node *core.IpfsNode, p path.Path, compression int) (io.Reader, error) {
|
||||||
dagnode, err := core.Resolve(ctx, node, pathToResolve)
|
dagnode, err := core.Resolve(ctx, node, p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return utar.NewReader(pathToResolve, node.DAG, dagnode, compression)
|
return utar.NewReader(p, node.DAG, dagnode, compression)
|
||||||
}
|
}
|
||||||
|
|
||||||
// getZip is equivalent to `ipfs getdag $hash | gzip`
|
// getZip is equivalent to `ipfs getdag $hash | gzip`
|
||||||
func getZip(ctx context.Context, node *core.IpfsNode, pathToResolve path.Path, compression int) (io.Reader, error) {
|
func getZip(ctx context.Context, node *core.IpfsNode, p path.Path, compression int) (io.Reader, error) {
|
||||||
dagnode, err := core.Resolve(ctx, node, pathToResolve)
|
dagnode, err := core.Resolve(ctx, node, p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -88,15 +88,9 @@ Publish an <ipfs-path> to another public key (not implemented):
|
|||||||
pstr = args[0]
|
pstr = args[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
p, err := path.ParsePath(pstr)
|
|
||||||
if err != nil {
|
|
||||||
res.SetError(fmt.Errorf("failed to validate path: %v", err), cmds.ErrNormal)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO n.Keychain.Get(name).PrivKey
|
// TODO n.Keychain.Get(name).PrivKey
|
||||||
// TODO(cryptix): is req.Context().Context a child of n.Context()?
|
// TODO(cryptix): is req.Context().Context a child of n.Context()?
|
||||||
output, err := publish(req.Context().Context, n, n.PrivateKey, p)
|
output, err := publish(req.Context().Context, n, n.PrivateKey, path.Path(pstr))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
res.SetError(err, cmds.ErrNormal)
|
res.SetError(err, cmds.ErrNormal)
|
||||||
return
|
return
|
||||||
|
16
path/path.go
16
path/path.go
@ -61,12 +61,15 @@ func ParsePath(txt string) (Path, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if parts[0] != "" {
|
if parts[0] != "" {
|
||||||
return "", ErrBadPath
|
if _, err := ParseKeyToPath(parts[0]); err != nil {
|
||||||
|
return "", ErrBadPath
|
||||||
|
}
|
||||||
|
// The case when the path starts with hash without a protocol prefix
|
||||||
|
return Path("/ipfs/" + txt), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if parts[1] == "ipfs" {
|
if parts[1] == "ipfs" {
|
||||||
_, err := ParseKeyToPath(parts[2])
|
if _, err := ParseKeyToPath(parts[2]); err != nil {
|
||||||
if err != nil {
|
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
} else if parts[1] != "ipns" {
|
} else if parts[1] != "ipns" {
|
||||||
@ -77,13 +80,16 @@ func ParsePath(txt string) (Path, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ParseKeyToPath(txt string) (Path, error) {
|
func ParseKeyToPath(txt string) (Path, error) {
|
||||||
|
if txt == "" {
|
||||||
|
return "", ErrNoComponents
|
||||||
|
}
|
||||||
|
|
||||||
chk := b58.Decode(txt)
|
chk := b58.Decode(txt)
|
||||||
if len(chk) == 0 {
|
if len(chk) == 0 {
|
||||||
return "", errors.New("not a key")
|
return "", errors.New("not a key")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := mh.Cast(chk)
|
if _, err := mh.Cast(chk); err != nil {
|
||||||
if err != nil {
|
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return FromKey(key.Key(chk)), nil
|
return FromKey(key.Key(chk)), nil
|
||||||
|
@ -65,6 +65,11 @@ func SplitAbsPath(fpath Path) (mh.Multihash, []string, error) {
|
|||||||
// ResolvePath fetches the node for given path. It returns the last item
|
// ResolvePath fetches the node for given path. It returns the last item
|
||||||
// returned by ResolvePathComponents.
|
// returned by ResolvePathComponents.
|
||||||
func (s *Resolver) ResolvePath(ctx context.Context, fpath Path) (*merkledag.Node, error) {
|
func (s *Resolver) ResolvePath(ctx context.Context, fpath Path) (*merkledag.Node, error) {
|
||||||
|
// validate path
|
||||||
|
if err := fpath.IsValid(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
nodes, err := s.ResolvePathComponents(ctx, fpath)
|
nodes, err := s.ResolvePathComponents(ctx, fpath)
|
||||||
if err != nil || nodes == nil {
|
if err != nil || nodes == nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
Reference in New Issue
Block a user