Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

*: Convert slices to arrays instead of copy where possible #595

Merged
merged 4 commits into from
Jul 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@

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")

Check warning on line 52 in bearer/bearer.go

View check run for this annotation

Codecov / codecov/patch

bearer/bearer.go#L52

Added line #L52 was not covered by tests
}
} 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 @@
}
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)

Check warning on line 443 in client/container.go

View check run for this annotation

Codecov / codecov/patch

client/container.go#L443

Added line #L443 was not covered by tests
return
}

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

Check warning on line 447 in client/container.go

View check run for this annotation

Codecov / codecov/patch

client/container.go#L447

Added line #L447 was not covered by tests
}
}

// 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 @@
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

Check warning on line 75 in container/id/id.go

View check run for this annotation

Codecov / codecov/patch

container/id/id.go#L75

Added line #L75 was not covered by tests
}

// 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 @@
}
}

// 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)

Check warning on line 95 in eacl/table.go

View check run for this annotation

Codecov / codecov/patch

eacl/table.go#L95

Added line #L95 was not covered by tests
}
}

// 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 @@
}

// 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 @@

// 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 @@

// 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 @@

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
Loading