From 774b5baa5aa5772b29865e8a570025d94ec34d2a Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Wed, 1 Jun 2022 10:22:09 -0600 Subject: better error tolerance --- pkg/btrfs/btrfsitem/item_empty.go | 2 +- pkg/btrfs/btrfsitem/items.go | 39 +++++++++++++++++++++++++++++++++------ 2 files changed, 34 insertions(+), 7 deletions(-) (limited to 'pkg/btrfs/btrfsitem') diff --git a/pkg/btrfs/btrfsitem/item_empty.go b/pkg/btrfs/btrfsitem/item_empty.go index ed0f66f..fe7ae90 100644 --- a/pkg/btrfs/btrfsitem/item_empty.go +++ b/pkg/btrfs/btrfsitem/item_empty.go @@ -5,5 +5,5 @@ import ( ) type Empty struct { // UNTYPED=0, QGROUP_RELATION=246 - binstruct.End `bin:"off=48"` + binstruct.End `bin:"off=0"` } diff --git a/pkg/btrfs/btrfsitem/items.go b/pkg/btrfs/btrfsitem/items.go index 91b7029..3c4392e 100644 --- a/pkg/btrfs/btrfsitem/items.go +++ b/pkg/btrfs/btrfsitem/items.go @@ -14,19 +14,46 @@ type Item interface { isItem() } -func UnmarshalItem(keytyp Type, dat []byte) (Item, error) { +type Error struct { + Dat []byte + Err error +} + +func (Error) isItem() {} + +func (o Error) MarshalBinary() ([]byte, error) { + return o.Dat, nil +} + +func (o *Error) UnmarshalBinary(dat []byte) (int, error) { + o.Dat = dat + return len(dat), nil +} + +// Rather than returning a separate error value, return an Error item. +func UnmarshalItem(keytyp Type, dat []byte) Item { gotyp, ok := keytype2gotype[keytyp] if !ok { - return nil, fmt.Errorf("btrfsitem.UnmarshalItem: unknown item type: %v", keytyp) + return Error{ + Dat: dat, + Err: fmt.Errorf("btrfsitem.UnmarshalItem(typ=%v, dat): unknown item type", keytyp), + } } retPtr := reflect.New(gotyp) n, err := binstruct.Unmarshal(dat, retPtr.Interface()) if err != nil { - return nil, fmt.Errorf("btrfsitem.UnmarshalItem: %w", err) + return Error{ + Dat: dat, + Err: fmt.Errorf("btrfsitem.UnmarshalItem(typ=%v, dat): %w", keytyp, err), + } + } if n < len(dat) { - return nil, fmt.Errorf("btrfsitem.UnmarshalItem: left over data: got %d bytes but only consumed %d", - len(dat), n) + return Error{ + Dat: dat, + Err: fmt.Errorf("btrfsitem.UnmarshalItem(typ=%v, dat): left over data: got %d bytes but only consumed %d", + keytyp, len(dat), n), + } } - return retPtr.Elem().Interface().(Item), nil + return retPtr.Elem().Interface().(Item) } -- cgit v1.2.3-54-g00ecf