Skip to content

Commit 32a4a1f

Browse files
authored
fix(manifest): infer refBytesSize at marshal time when never set (#5484)
1 parent 025d9d4 commit 32a4a1f

2 files changed

Lines changed: 58 additions & 0 deletions

File tree

pkg/manifest/mantaray/marshal.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,24 @@ func (n *Node) MarshalBinary() (bytes []byte, err error) {
105105
return nil, ErrInvalidInput
106106
}
107107

108+
// Infer refBytesSize when Add() never set it (directory-only adds): use
109+
// our own entry width if present, else the first child ref's width.
110+
// Without this, the header reports refBytesSize=0 while the body still
111+
// carries full-width data, and the v0.2 reader at line 280 silently drops
112+
// every fork.
113+
if n.refBytesSize == 0 {
114+
if len(n.entry) > 0 {
115+
n.refBytesSize = len(n.entry)
116+
} else {
117+
for _, f := range n.forks {
118+
if len(f.ref) > 0 {
119+
n.refBytesSize = len(f.ref)
120+
break
121+
}
122+
}
123+
}
124+
}
125+
108126
// header
109127

110128
headerBytes := make([]byte, nodeHeaderSize)

pkg/manifest/mantaray/persist_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,46 @@ func TestPersistRemove(t *testing.T) {
174174
}
175175
}
176176

177+
// TestPersistDirectoryOnlyAdds covers the case where every Add() to a node
178+
// carries an empty entry (only forks/metadata), so the lazy-init in Add()
179+
// never sets refBytesSize. Without the marshal-time inference, the header
180+
// would report refBytesSize=0 even though the children have full-width refs,
181+
// and the v0.2 reader would silently drop every fork.
182+
func TestPersistDirectoryOnlyAdds(t *testing.T) {
183+
t.Parallel()
184+
185+
ctx := context.Background()
186+
ls := mantaray.LoadSaver(newMockLoadSaver())
187+
188+
n := mantaray.New()
189+
n.SetObfuscationKey(mantaray.ZeroObfuscationKey)
190+
191+
paths := [][]byte{[]byte("foo"), []byte("bar"), []byte("baz")}
192+
for _, p := range paths {
193+
// empty entry; only metadata. Mirrors bee/pkg/api/bzz.go:266 which
194+
// adds the root path with swarm.ZeroAddress (a nil []byte).
195+
if err := n.Add(ctx, p, nil, map[string]string{"k": "v"}, ls); err != nil {
196+
t.Fatalf("add %q: %v", p, err)
197+
}
198+
}
199+
200+
if err := n.Save(ctx, ls); err != nil {
201+
t.Fatalf("save: %v", err)
202+
}
203+
ref := n.Reference()
204+
205+
nn := mantaray.NewNodeRef(ref)
206+
for _, p := range paths {
207+
ln, err := nn.LookupNode(ctx, p, ls)
208+
if err != nil {
209+
t.Fatalf("lookup %q: %v", p, err)
210+
}
211+
if v := ln.Metadata()["k"]; v != "v" {
212+
t.Fatalf("lookup %q: expected metadata k=v, got %q", p, v)
213+
}
214+
}
215+
}
216+
177217
type (
178218
addr [32]byte
179219
mockLoadSaver struct {

0 commit comments

Comments
 (0)