Skip to content
This repository was archived by the owner on Jun 27, 2023. It is now read-only.

Commit fede2ed

Browse files
ajnavarroguseggert
andauthored
Fix: panic when childer is nil (#127)
* Fix panic when childer is nil Signed-off-by: Antonio Navarro Perez <[email protected]> * Apply suggestions from code review Co-authored-by: Gus Eggert <[email protected]> Signed-off-by: Antonio Navarro Perez <[email protected]> Co-authored-by: Gus Eggert <[email protected]>
1 parent 2c23c3e commit fede2ed

File tree

2 files changed

+49
-5
lines changed

2 files changed

+49
-5
lines changed

hamt/hamt.go

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,12 @@ type Shard struct {
8686

8787
// NewShard creates a new, empty HAMT shard with the given size.
8888
func NewShard(dserv ipld.DAGService, size int) (*Shard, error) {
89-
ds, err := makeShard(dserv, size)
89+
return NewShardValue(dserv, size, "", nil)
90+
}
91+
92+
// NewShardValue creates a new, empty HAMT shard with the given key, value and size.
93+
func NewShardValue(dserv ipld.DAGService, size int, key string, value *ipld.Link) (*Shard, error) {
94+
ds, err := makeShard(dserv, size, key, value)
9095
if err != nil {
9196
return nil, err
9297
}
@@ -96,7 +101,7 @@ func NewShard(dserv ipld.DAGService, size int) (*Shard, error) {
96101
return ds, nil
97102
}
98103

99-
func makeShard(ds ipld.DAGService, size int) (*Shard, error) {
104+
func makeShard(ds ipld.DAGService, size int, key string, val *ipld.Link) (*Shard, error) {
100105
lg2s, err := Logtwo(size)
101106
if err != nil {
102107
return nil, err
@@ -109,6 +114,9 @@ func makeShard(ds ipld.DAGService, size int) (*Shard, error) {
109114
childer: newChilder(ds, size),
110115
tableSize: size,
111116
dserv: ds,
117+
118+
key: key,
119+
val: val,
112120
}
113121

114122
s.childer.sd = s
@@ -138,7 +146,7 @@ func NewHamtFromDag(dserv ipld.DAGService, nd ipld.Node) (*Shard, error) {
138146

139147
size := int(fsn.Fanout())
140148

141-
ds, err := makeShard(dserv, size)
149+
ds, err := makeShard(dserv, size, "", nil)
142150
if err != nil {
143151
return nil, err
144152
}
@@ -214,7 +222,7 @@ func (ds *Shard) Node() (ipld.Node, error) {
214222

215223
func (ds *Shard) makeShardValue(lnk *ipld.Link) (*Shard, error) {
216224
lnk2 := *lnk
217-
s, err := makeShard(ds.dserv, ds.tableSize)
225+
s, err := makeShard(ds.dserv, ds.tableSize, "", nil)
218226
if err != nil {
219227
return nil, err
220228
}
@@ -795,7 +803,11 @@ func (s *childer) insert(key string, lnk *ipld.Link, idx int) error {
795803

796804
lnk.Name = s.sd.linkNamePrefix(idx) + key
797805
i := s.sliceIndex(idx)
798-
sd := &Shard{key: key, val: lnk}
806+
807+
sd, err := NewShardValue(s.dserv, 256, key, lnk)
808+
if err != nil {
809+
return err
810+
}
799811

800812
s.children = append(s.children[:i], append([]*Shard{sd}, s.children[i:]...)...)
801813
s.links = append(s.links[:i], append([]*ipld.Link{nil}, s.links[i:]...)...)

hamt/hamt_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,38 @@ func TestDuplicateAddShard(t *testing.T) {
435435
}
436436
}
437437

438+
// fix https://github.com/ipfs/kubo/issues/9063
439+
func TestSetLink(t *testing.T) {
440+
ds := mdtest.Mock()
441+
dir, _ := NewShard(ds, 256)
442+
_, s, err := makeDir(ds, 300)
443+
if err != nil {
444+
t.Fatal(err)
445+
}
446+
447+
lnk, err := s.Link()
448+
if err != nil {
449+
t.Fatal(err)
450+
}
451+
452+
ctx := context.Background()
453+
454+
err = dir.SetLink(ctx, "test", lnk)
455+
if err != nil {
456+
t.Fatal(err)
457+
}
458+
459+
if len(dir.childer.children) != 1 {
460+
t.Fatal("no child")
461+
}
462+
463+
for _, sh := range dir.childer.children {
464+
if sh.childer == nil {
465+
t.Fatal("no childer on shard")
466+
}
467+
}
468+
}
469+
438470
func TestLoadFailsFromNonShard(t *testing.T) {
439471
ds := mdtest.Mock()
440472
nd := ft.EmptyDirNode()

0 commit comments

Comments
 (0)