Skip to content

Commit

Permalink
Factor out code to validate unixfs node and add unit tests.
Browse files Browse the repository at this point in the history
License: MIT
Signed-off-by: Kevin Atkinson <k@kevina.org>
  • Loading branch information
kevina committed Feb 16, 2018
1 parent 055026c commit b1c5ffb
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 16 deletions.
21 changes: 5 additions & 16 deletions unixfs/io/pbdagreader.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,25 +52,14 @@ var _ DagReader = (*PBDagReader)(nil)

// NewPBFileReader constructs a new PBFileReader.
func NewPBFileReader(ctx context.Context, n *mdag.ProtoNode, pb *ftpb.Data, serv ipld.NodeGetter) (*PBDagReader, error) {
err := ValidatePB(n, pb)
if err != nil {
return nil, err
}

curLinks := getLinkCids(n)
data := pb.GetData()

// validate
if len(curLinks) != len(pb.Blocksizes) {
return nil, errors.New("unixfs ill-formed, number of links does not batch blocksize count")
}
total := uint64(len(data))
for _, blocksize := range pb.Blocksizes {
total += blocksize
}
if pb.Filesize == nil {
return nil, errors.New("unixfs ill-formed, filesize field missing")
}
if total != *pb.Filesize {
return nil, fmt.Errorf("unixfs ill-formed, actual size of %d does not match size in filesize field (%d)",
total, *pb.Filesize)
}

fctx, cancel := context.WithCancel(ctx)
return &PBDagReader{
node: n,
Expand Down
18 changes: 18 additions & 0 deletions unixfs/unixfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package unixfs

import (
"errors"
"fmt"

proto "gx/ipfs/QmZ4Qi3GaRbjcx28Sme5eMH7RQjGkt8wHxt2a65oLaeFEV/gogo-protobuf/proto"

Expand Down Expand Up @@ -258,3 +259,20 @@ func BytesForMetadata(m *Metadata) ([]byte, error) {
func EmptyDirNode() *dag.ProtoNode {
return dag.NodeWithData(FolderPBData())
}

// ValidatePB validates a unixfs protonode.
func ValidatePB(n *dag.ProtoNode, pb *pb.Data) error {
if len(n.Links()) != len(pb.Blocksizes) {
return errors.New("unixfs ill-formed, number of links does not batch blocksize count")
}
total := uint64(len(pb.GetData()))
for _, blocksize := range pb.Blocksizes {
total += blocksize
}
if total != pb.GetFilesize() {
return fmt.Errorf("unixfs ill-formed, actual size of %d does not match size in filesize field with value %d",
total, pb.GetFilesize())
}

return nil
}
39 changes: 39 additions & 0 deletions unixfs/unixfs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package unixfs

import (
"bytes"
"encoding/hex"
"testing"

proto "gx/ipfs/QmZ4Qi3GaRbjcx28Sme5eMH7RQjGkt8wHxt2a65oLaeFEV/gogo-protobuf/proto"

dag "github.com/ipfs/go-ipfs/merkledag"
pb "github.com/ipfs/go-ipfs/unixfs/pb"
)

Expand Down Expand Up @@ -159,3 +161,40 @@ func TestMetadata(t *testing.T) {
}

}

// originally from test/sharness/t0110-gateway-data/foofoo.block, does not have blocksize defined
// contents: {"data":"CAIYBg==","links":[{"Cid":{"/":"QmcJw6x4bQr7oFnVnF6i8SLcJvhXjaxWvj54FYXmZ4Ct6p"},"Name":"","Size":0},{"Cid":{"/":"QmcJw6x4bQr7oFnVnF6i8SLcJvhXjaxWvj54FYXmZ4Ct6p"},"Name":"","Size":0}]}
const noBlocksizeHex = "0A040802180612240A221220CF92FDEFCDC34CAC009C8B05EB662BE0618DB9DE55ECD42785E9EC6712F8DF6512240A221220CF92FDEFCDC34CAC009C8B05EB662BE0618DB9DE55ECD42785E9EC6712F8DF65"

func TestValidatePB(t *testing.T) {
noBlocksize, err := hex.DecodeString(noBlocksizeHex)
if err != nil {
t.Fatal(err)
}
nd, err := dag.DecodeProtobuf(noBlocksize)
if err != nil {
t.Fatal(err)
}
fd, err := FromBytes(nd.Data())
if err != nil {
t.Fatal(err)
}
err = ValidatePB(nd, fd)
if err == nil {
t.Fatal("invalid unixfs node (with no blocksizes) validated")
}
// give node blocksizes
fd.Blocksizes = []uint64{3, 3}
// should be ok
err = ValidatePB(nd, fd)
if err != nil {
t.Fatalf("valid node failed to validate: %v", err)
}
// give node incorrect filesize
var filesize uint64 = 8
fd.Filesize = &filesize
err = ValidatePB(nd, fd)
if err == nil {
t.Fatal("invalid unixfs node (with incorrect filesize) validated")
}
}

0 comments on commit b1c5ffb

Please sign in to comment.