Skip to content

Commit

Permalink
*: Convert slices to arrays instead of copy where possible (#595)
Browse files Browse the repository at this point in the history
  • Loading branch information
carpawell committed Jul 9, 2024
2 parents 0efacfb + d5a5fbc commit 1478127
Show file tree
Hide file tree
Showing 10 changed files with 121 additions and 71 deletions.
4 changes: 3 additions & 1 deletion bearer/bearer.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ func (b *Token) readFromV2(m acl.BearerToken, checkFieldPresence bool) error {

eaclTable := body.GetEACL()
if b.eaclTableSet = eaclTable != nil; b.eaclTableSet {
b.eaclTable = *eacl.NewTableFromV2(eaclTable)
if err = b.eaclTable.ReadFromV2(*eaclTable); err != nil {
return fmt.Errorf("invalid eACL")
}
} else if checkFieldPresence {
return errors.New("missing eACL table")
}
Expand Down
9 changes: 5 additions & 4 deletions client/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -437,14 +437,15 @@ func (c *Client) ContainerEACL(ctx context.Context, id cid.ID, prm PrmContainerE
}
cc.result = func(r responseV2) {
resp := r.(*v2container.GetExtendedACLResponse)

const fieldEACL = "eACL"
eACL := resp.GetBody().GetEACL()
if eACL == nil {
cc.err = newErrMissingResponseField("eACL")
cc.err = newErrMissingResponseField(fieldEACL)
return
}

res = *eacl.NewTableFromV2(eACL)
if cc.err = res.ReadFromV2(*eACL); cc.err != nil {
cc.err = newErrInvalidResponseField(fieldEACL, cc.err)
}
}

// process call
Expand Down
4 changes: 2 additions & 2 deletions container/id/id.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,14 @@ func (id *ID) Decode(src []byte) error {
return fmt.Errorf("invalid length %d", len(src))
}

copy(id[:], src)
*id = ID(src)

return nil
}

// SetSHA256 sets container identifier value to SHA256 checksum of container structure.
func (id *ID) SetSHA256(v [sha256.Size]byte) {
copy(id[:], v[:])
*id = v
}

// Equals defines a comparison relation between two ID instances.
Expand Down
89 changes: 50 additions & 39 deletions eacl/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,50 @@ func (t *Table) AddRecord(r *Record) {
}
}

// ReadFromV2 reads Table from the [v2acl.Table] message. Returns an error if
// the message is malformed according to the NeoFS API V2 protocol. The message
// must not be nil.
//
// ReadFromV2 is intended to be used by the NeoFS API V2 client/server
// implementation only and is not expected to be directly used by applications.
//
// See also [Table.ToV2].
func (t *Table) ReadFromV2(m v2acl.Table) error {
// set container id
if id := m.GetContainerID(); id != nil {
if t.cid == nil {
t.cid = new(cid.ID)
}
if err := t.cid.ReadFromV2(*id); err != nil {
return fmt.Errorf("invalid container ID: %w", err)
}
}

// set version
if v := m.GetVersion(); v != nil {
ver := version.Version{}
ver.SetMajor(v.GetMajor())
ver.SetMinor(v.GetMinor())

t.SetVersion(ver)
}

// set eacl records
v2records := m.GetRecords()
t.records = make([]Record, len(v2records))

for i := range v2records {
t.records[i] = *NewRecordFromV2(&v2records[i])
}

return nil
}

// ToV2 converts Table to v2 acl.EACLTable message.
//
// Nil Table converts to nil.
//
// See also [Table.ReadFromV2].
func (t *Table) ToV2() *v2acl.Table {
if t == nil {
return nil
Expand Down Expand Up @@ -133,6 +174,9 @@ func CreateTable(cid cid.ID) *Table {
}

// NewTableFromV2 converts v2 acl.EACLTable message to Table.
//
// Deprecated: BUG: container ID length is not checked. Use [Table.ReadFromV2]
// instead.
func NewTableFromV2(table *v2acl.Table) *Table {
t := new(Table)

Expand Down Expand Up @@ -187,20 +231,11 @@ func (t Table) SignedData() []byte {

// Unmarshal unmarshals protobuf binary representation of Table.
func (t *Table) Unmarshal(data []byte) error {
fV2 := new(v2acl.Table)
if err := fV2.Unmarshal(data); err != nil {
return err
}

// format checks
err := checkFormat(fV2)
if err != nil {
var m v2acl.Table
if err := m.Unmarshal(data); err != nil {
return err
}

*t = *NewTableFromV2(fV2)

return nil
return t.ReadFromV2(m)
}

// MarshalJSON encodes Table to protobuf JSON format.
Expand All @@ -210,19 +245,11 @@ func (t *Table) MarshalJSON() ([]byte, error) {

// UnmarshalJSON decodes Table from protobuf JSON format.
func (t *Table) UnmarshalJSON(data []byte) error {
tV2 := new(v2acl.Table)
if err := tV2.UnmarshalJSON(data); err != nil {
return err
}

err := checkFormat(tV2)
if err != nil {
var m v2acl.Table
if err := m.UnmarshalJSON(data); err != nil {
return err
}

*t = *NewTableFromV2(tV2)

return nil
return t.ReadFromV2(m)
}

// EqualTables compares Table with each other.
Expand All @@ -249,19 +276,3 @@ func EqualTables(t1, t2 Table) bool {

return true
}

func checkFormat(v2 *v2acl.Table) error {
var cID cid.ID

cidV2 := v2.GetContainerID()
if cidV2 == nil {
return nil
}

err := cID.ReadFromV2(*cidV2)
if err != nil {
return fmt.Errorf("could not convert V2 container ID: %w", err)
}

return nil
}
3 changes: 3 additions & 0 deletions eacl/table_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ func TestTable(t *testing.T) {

newTable := eacl.NewTableFromV2(v2)
require.Equal(t, table, newTable)
var res eacl.Table
require.NoError(t, res.ReadFromV2(*v2))
require.Equal(t, table, newTable)

t.Run("new from nil v2 table", func(t *testing.T) {
require.Equal(t, new(eacl.Table), eacl.NewTableFromV2(nil))
Expand Down
12 changes: 4 additions & 8 deletions object/id/id.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,14 @@ func (id *ID) Decode(src []byte) error {
return fmt.Errorf("invalid length %d", len(src))
}

copy(id[:], src)
*id = ID(src)

return nil
}

// SetSHA256 sets object identifier value to SHA256 checksum.
func (id *ID) SetSHA256(v [sha256.Size]byte) {
copy(id[:], v[:])
*id = v
}

// Equals defines a comparison relation between two ID instances.
Expand Down Expand Up @@ -141,9 +141,7 @@ func (id *ID) Unmarshal(data []byte) error {
return err
}

copy(id[:], v2.GetValue())

return nil
return id.ReadFromV2(v2)
}

// MarshalJSON encodes ID to protobuf JSON format.
Expand All @@ -161,7 +159,5 @@ func (id *ID) UnmarshalJSON(data []byte) error {
return err
}

copy(id[:], v2.GetValue())

return nil
return id.ReadFromV2(v2)
}
49 changes: 49 additions & 0 deletions object/id/id_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,3 +180,52 @@ func TestID_Encode(t *testing.T) {
require.Equal(t, emptyID, id.EncodeToString())
})
}

func TestID_Unmarshal(t *testing.T) {
t.Run("invalid value length", func(t *testing.T) {
var id ID
var m refs.ObjectID
for _, tc := range []struct {
err string
val []byte
}{
{"invalid length 0", nil},
{"invalid length 0", []byte{}},
{"invalid length 31", make([]byte, 31)},
{"invalid length 33", make([]byte, 33)},
} {
m.SetValue(tc.val)
b := m.StableMarshal(nil)
require.EqualError(t, id.Unmarshal(b), tc.err)
}
})
}

func TestIDDecodingFailures(t *testing.T) {
var id ID
var m refs.ObjectID
for _, tc := range []struct {
err string
corrupt func(*refs.ObjectID)
}{
{"invalid length 0", func(m *refs.ObjectID) { m.SetValue(nil) }},
{"invalid length 0", func(m *refs.ObjectID) { m.SetValue([]byte{}) }},
{"invalid length 31", func(m *refs.ObjectID) { m.SetValue(make([]byte, 31)) }},
{"invalid length 33", func(m *refs.ObjectID) { m.SetValue(make([]byte, 33)) }},
} {
id.WriteToV2(&m)
tc.corrupt(&m)
t.Run(tc.err+"/api", func(t *testing.T) {
require.EqualError(t, id.ReadFromV2(m), tc.err)
})
t.Run(tc.err+"/binary", func(t *testing.T) {
b := m.StableMarshal(nil)
require.EqualError(t, id.Unmarshal(b), tc.err)
})
t.Run(tc.err+"/json", func(t *testing.T) {
b, err := m.MarshalJSON()
require.NoError(t, err, tc.err)
require.EqualError(t, id.UnmarshalJSON(b), tc.err)
})
}
}
10 changes: 2 additions & 8 deletions object/search_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -341,11 +341,8 @@ func TestSearchFilters_AddPayloadHashFilter(t *testing.T) {
func ExampleSearchFilters_AddPayloadHashFilter() {
hash, _ := hex.DecodeString("66842cfea090b1d906b52400fae49d86df078c0670f2bdd059ba289ebe24a498")

var v [sha256.Size]byte
copy(v[:], hash[:sha256.Size])

var cs checksum.Checksum
cs.SetSHA256(v)
cs.SetSHA256([sha256.Size]byte(hash))

fmt.Println(hex.EncodeToString(cs.Value()))
// Output: 66842cfea090b1d906b52400fae49d86df078c0670f2bdd059ba289ebe24a498
Expand Down Expand Up @@ -377,11 +374,8 @@ func TestSearchFilters_AddHomomorphicHashFilter(t *testing.T) {
func ExampleSearchFilters_AddHomomorphicHashFilter() {
hash, _ := hex.DecodeString("7e302ebb3937e810feb501965580c746048db99cebd095c3ce27022407408bf904dde8d9aa8085d2cf7202345341cc947fa9d722c6b6699760d307f653815d0c")

var v [tz.Size]byte
copy(v[:], hash[:tz.Size])

var cs checksum.Checksum
cs.SetTillichZemor(v)
cs.SetTillichZemor([tz.Size]byte(hash))

fmt.Println(hex.EncodeToString(cs.Value()))
// Output: 7e302ebb3937e810feb501965580c746048db99cebd095c3ce27022407408bf904dde8d9aa8085d2cf7202345341cc947fa9d722c6b6699760d307f653815d0c
Expand Down
10 changes: 2 additions & 8 deletions object/slicer/slicer.go
Original file line number Diff line number Diff line change
Expand Up @@ -600,17 +600,11 @@ func (x *PayloadWriter) _writeChild(ctx context.Context, meta dynamicObjectMetad
func flushObjectMetadata(signer neofscrypto.Signer, meta dynamicObjectMetadata, header *object.Object) (oid.ID, error) {
var cs checksum.Checksum

var csBytes [sha256.Size]byte
copy(csBytes[:], meta.checksum.Sum(nil))

cs.SetSHA256(csBytes)
cs.SetSHA256([sha256.Size]byte(meta.checksum.Sum(nil)))
header.SetPayloadChecksum(cs)

if meta.homomorphicChecksum != nil {
var csHomoBytes [tz.Size]byte
copy(csHomoBytes[:], meta.homomorphicChecksum.Sum(nil))

cs.SetTillichZemor(csHomoBytes)
cs.SetTillichZemor([tz.Size]byte(meta.homomorphicChecksum.Sum(nil)))
header.SetPayloadHomomorphicHash(cs)
}

Expand Down
2 changes: 1 addition & 1 deletion session/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ type contextReader func(session.TokenContext, bool) error

func (x commonData) copyTo(dst *commonData) {
dst.idSet = x.idSet
copy(dst.id[:], x.id[:])
dst.id = x.id

dst.issuerSet = x.issuerSet
iss := x.issuer
Expand Down

0 comments on commit 1478127

Please sign in to comment.