From 02fccc8c29d6f638efee0302868242d805bd7711 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sat, 4 Jun 2022 20:19:37 -0600 Subject: Preserve padding --- pkg/btrfs/types_btree.go | 15 ++++++++++++++- pkg/btrfs/util.go | 7 +++++++ 2 files changed, 21 insertions(+), 1 deletion(-) (limited to 'pkg') diff --git a/pkg/btrfs/types_btree.go b/pkg/btrfs/types_btree.go index f609b8c..0be7b48 100644 --- a/pkg/btrfs/types_btree.go +++ b/pkg/btrfs/types_btree.go @@ -20,6 +20,8 @@ type Node struct { // the node's type, as specified in the header) BodyInternal []KeyPointer // for internal nodes BodyLeaf []Item // for leave nodes + + Padding []byte } type NodeHeader struct { @@ -118,9 +120,11 @@ func (node *Node) UnmarshalBinary(nodeBuf []byte) (int, error) { } node.BodyInternal = append(node.BodyInternal, item) } - return n, nil + node.Padding = nodeBuf[n:] + return len(nodeBuf), nil } else { // leaf node + firstRead := len(nodeBuf) lastRead := 0 for i := uint32(0); i < node.Head.NumItems; i++ { var item Item @@ -137,11 +141,13 @@ func (node *Node) UnmarshalBinary(nodeBuf []byte) (int, error) { dataOff+dataSize, len(nodeBuf)) } dataBuf := nodeBuf[dataOff : dataOff+dataSize] + firstRead = min(firstRead, dataOff) lastRead = max(lastRead, dataOff+dataSize) item.Body = btrfsitem.UnmarshalItem(item.Head.Key.ItemType, dataBuf) node.BodyLeaf = append(node.BodyLeaf, item) } + node.Padding = nodeBuf[n:firstRead] return max(n, lastRead), nil } } @@ -166,6 +172,7 @@ func (node Node) MarshalBinary() ([]byte, error) { return dat, err } } + dat = append(dat, node.Padding...) if copy(ret, dat) < len(dat) { return ret, fmt.Errorf("btrfs.Node.MarshalBinary: need at least %d bytes, but .Size is only %d", len(dat), node.Size) @@ -177,6 +184,7 @@ func (node Node) MarshalBinary() ([]byte, error) { len(dat), node.Size) } n := len(dat) + minData := len(ret) for _, item := range node.BodyLeaf { dat, err = binstruct.Marshal(item.Head) if err != nil { @@ -193,11 +201,16 @@ func (node Node) MarshalBinary() ([]byte, error) { return ret, err } dataOff := binstruct.StaticSize(NodeHeader{}) + int(item.Head.DataOffset) + minData = min(minData, dataOff) if copy(ret[dataOff:], dat) < len(dat) { return ret, fmt.Errorf("btrfs.Node.MarshalBinary: need at least %d bytes, but .Size is only %d", dataOff+len(dat), node.Size) } } + if copy(ret[n:minData], node.Padding) < len(node.Padding) { + return ret, fmt.Errorf("btrfs.Node.MarshalBinary: not enough room left for padding") + } + } return ret, nil } diff --git a/pkg/btrfs/util.go b/pkg/btrfs/util.go index 312ec75..671d6fc 100644 --- a/pkg/btrfs/util.go +++ b/pkg/btrfs/util.go @@ -19,3 +19,10 @@ func max[T constraints.Ordered](a, b T) T { } return b } + +func min[T constraints.Ordered](a, b T) T { + if a < b { + return a + } + return b +} -- cgit v1.2.3-2-g168b