diff --git a/pkg/core/container/fmt.go b/pkg/core/container/fmt.go index 69275f38..e63673e5 100644 --- a/pkg/core/container/fmt.go +++ b/pkg/core/container/fmt.go @@ -9,7 +9,11 @@ import ( "github.com/nspcc-dev/neofs-api-go/pkg/owner" ) -var errNilPolicy = errors.New("placement policy is nil") +var ( + errNilPolicy = errors.New("placement policy is nil") + errRepeatedAttributes = errors.New("repeated attributes found") + errEmptyAttribute = errors.New("empty attribute found") +) // CheckFormat conducts an initial check of the v2 container data. // @@ -32,5 +36,20 @@ func CheckFormat(c *container.Container) error { return fmt.Errorf("incorrect nonce: %w", err) } + // check if there are repeated attributes + attrs := c.Attributes() + uniqueAttr := make(map[string]struct{}, len(attrs)) + for _, attr := range attrs { + if _, exists := uniqueAttr[attr.Key()]; exists { + return errRepeatedAttributes + } + + if attr.Value() == "" { + return errEmptyAttribute + } + + uniqueAttr[attr.Key()] = struct{}{} + } + return nil } diff --git a/pkg/core/container/fmt_test.go b/pkg/core/container/fmt_test.go index 34581182..024d597c 100644 --- a/pkg/core/container/fmt_test.go +++ b/pkg/core/container/fmt_test.go @@ -41,4 +41,30 @@ func TestCheckFormat(t *testing.T) { c.SetNonceUUID(uuid.New()) require.NoError(t, CheckFormat(c)) + + // set empty value attribute + attr1 := container.NewAttribute() + attr1.SetKey("attr") + attrs := container.Attributes{attr1} + + c.SetAttributes(attrs) + + require.ErrorIs(t, CheckFormat(c), errEmptyAttribute) + + // add same key attribute + attr2 := container.NewAttribute() + attr2.SetKey(attr1.Key()) + attr2.SetValue("val") + + attr1.SetValue(attr2.Value()) + + attrs = append(attrs, attr2) + + c.SetAttributes(attrs) + + require.ErrorIs(t, CheckFormat(c), errRepeatedAttributes) + + attr2.SetKey(attr1.Key() + "smth") + + require.NoError(t, CheckFormat(c)) }