diff --git a/importer/balanced/builder.go b/importer/balanced/builder.go index c15c56c62..4ea84df8f 100644 --- a/importer/balanced/builder.go +++ b/importer/balanced/builder.go @@ -51,7 +51,12 @@ func Layout(db *h.DagBuilderHelper) (ipld.Node, error) { } if root == nil { - root = db.NewUnixfsNode() + // this should only happen with an empty node, so return a leaf + var err error + root, err = db.NewLeaf(nil) + if err != nil { + return nil, err + } } out, err := db.Add(root) diff --git a/importer/helpers/dagbuilder.go b/importer/helpers/dagbuilder.go index 4fc49727d..3945b5ac8 100644 --- a/importer/helpers/dagbuilder.go +++ b/importer/helpers/dagbuilder.go @@ -122,6 +122,41 @@ func (db *DagBuilderHelper) NewUnixfsNode() *UnixfsNode { return n } +// NewLeaf creates a leaf node filled with data. If rawLeaves is +// defined than a raw leaf will be returned. Otherwise, if data is +// nil the type field will be TRaw (for backwards compatibility), if +// data is defined (but possibly empty) the type field will be TRaw. +func (db *DagBuilderHelper) NewLeaf(data []byte) (*UnixfsNode, error) { + if len(data) > BlockSizeLimit { + return nil, ErrSizeLimitExceeded + } + + if db.rawLeaves { + if db.prefix == nil { + return &UnixfsNode{ + rawnode: dag.NewRawNode(data), + raw: true, + }, nil + } + rawnode, err := dag.NewRawNodeWPrefix(data, *db.prefix) + if err != nil { + return nil, err + } + return &UnixfsNode{ + rawnode: rawnode, + raw: true, + }, nil + } + + if data == nil { + return db.NewUnixfsNode(), nil + } + + blk := db.newUnixfsBlock() + blk.SetData(data) + return blk, nil +} + // newUnixfsBlock creates a new Unixfs node to represent a raw data block func (db *DagBuilderHelper) newUnixfsBlock() *UnixfsNode { n := &UnixfsNode{ @@ -164,30 +199,7 @@ func (db *DagBuilderHelper) GetNextDataNode() (*UnixfsNode, error) { return nil, nil } - if len(data) > BlockSizeLimit { - return nil, ErrSizeLimitExceeded - } - - if db.rawLeaves { - if db.prefix == nil { - return &UnixfsNode{ - rawnode: dag.NewRawNode(data), - raw: true, - }, nil - } - rawnode, err := dag.NewRawNodeWPrefix(data, *db.prefix) - if err != nil { - return nil, err - } - return &UnixfsNode{ - rawnode: rawnode, - raw: true, - }, nil - } - - blk := db.newUnixfsBlock() - blk.SetData(data) - return blk, nil + return db.NewLeaf(data) } // SetPosInfo sets the offset information of a node using the fullpath and stat diff --git a/test/sharness/t0040-add-and-cat.sh b/test/sharness/t0040-add-and-cat.sh index b9c633b29..82c194e9e 100755 --- a/test/sharness/t0040-add-and-cat.sh +++ b/test/sharness/t0040-add-and-cat.sh @@ -166,6 +166,24 @@ test_add_cat_file() { echo "added $HASH .hello.txt" >expected && test_cmp expected actual ' + + test_expect_success "add zero length file" ' + touch zero-length-file && + ZEROHASH=$(ipfs add -q zero-length-file) && + echo $ZEROHASH + ' + + test_expect_success "zero length file has correct hash" ' + test "$ZEROHASH" = QmbFMke1KXqnYyBBWxB74N4c5SBnJMVAiMNRcGu6x1AwQH + ' + + test_expect_success "cat zero length file" ' + ipfs cat $ZEROHASH > zero-length-file_out + ' + + test_expect_success "make sure it looks good" ' + test_cmp zero-length-file zero-length-file_out + ' } test_add_cat_5MB() { @@ -221,6 +239,24 @@ test_add_cat_raw() { test_expect_success "make sure it looks good" ' test_cmp afile afile_out ' + + test_expect_success "add zero length file with raw-leaves" ' + touch zero-length-file && + ZEROHASH=$(ipfs add -q --raw-leaves zero-length-file) && + echo $ZEROHASH + ' + + test_expect_success "zero length file has correct hash" ' + test "$ZEROHASH" = zb2rhmy65F3REf8SZp7De11gxtECBGgUKaLdiDj7MCGCHxbDW + ' + + test_expect_success "cat zero length file" ' + ipfs cat $ZEROHASH > zero-length-file_out + ' + + test_expect_success "make sure it looks good" ' + test_cmp zero-length-file zero-length-file_out + ' } test_add_cat_expensive() {