diff --git a/s3api/controllers/bucket-put.go b/s3api/controllers/bucket-put.go index 04c0311f..860fb015 100644 --- a/s3api/controllers/bucket-put.go +++ b/s3api/controllers/bucket-put.go @@ -108,11 +108,16 @@ func (c S3ApiController) PutBucketOwnershipControls(ctx *fiber.Ctx) (*Response, } rulesCount := len(ownershipControls.Rules) - isValidOwnership := utils.IsValidOwnership(ownershipControls.Rules[0].ObjectOwnership) - if rulesCount != 1 || !isValidOwnership { - if rulesCount != 1 { - debuglogger.Logf("ownership control rules should be 1, got %v", rulesCount) - } + if rulesCount != 1 { + debuglogger.Logf("ownership control rules should be 1, got %v", rulesCount) + return &Response{ + MetaOpts: &MetaOptions{ + BucketOwner: parsedAcl.Owner, + }, + }, s3err.GetAPIError(s3err.ErrMalformedXML) + } + + if !utils.IsValidOwnership(ownershipControls.Rules[0].ObjectOwnership) { return &Response{ MetaOpts: &MetaOptions{ BucketOwner: parsedAcl.Owner, diff --git a/s3api/controllers/bucket-put_test.go b/s3api/controllers/bucket-put_test.go index bffe4662..c699eb8a 100644 --- a/s3api/controllers/bucket-put_test.go +++ b/s3api/controllers/bucket-put_test.go @@ -158,6 +158,11 @@ func TestS3ApiController_PutBucketOwnershipControls(t *testing.T) { ) assert.NoError(t, err) + emptyRulesBody, err := xml.Marshal( + s3response.OwnershipControls{}, + ) + assert.NoError(t, err) + tests := []struct { name string input testInput @@ -203,6 +208,19 @@ func TestS3ApiController_PutBucketOwnershipControls(t *testing.T) { err: s3err.GetAPIError(s3err.ErrMalformedXML), }, }, + { + name: "empty rules count", + input: testInput{ + locals: defaultLocals, + body: emptyRulesBody, + }, + output: testOutput{ + response: &Response{ + MetaOpts: &MetaOptions{BucketOwner: "root"}, + }, + err: s3err.GetAPIError(s3err.ErrMalformedXML), + }, + }, { name: "backend error", input: testInput{ diff --git a/tests/integration/PutBucketOwnershipControls.go b/tests/integration/PutBucketOwnershipControls.go index b9e116ec..ad0c823c 100644 --- a/tests/integration/PutBucketOwnershipControls.go +++ b/tests/integration/PutBucketOwnershipControls.go @@ -16,6 +16,8 @@ package integration import ( "context" + "net/http" + "time" "github.com/aws/aws-sdk-go-v2/service/s3" "github.com/aws/aws-sdk-go-v2/service/s3/types" @@ -94,6 +96,26 @@ func PutBucketOwnershipControls_invalid_ownership(s *S3Conf) error { }) } +func PutBucketOwnershipControls_empty_rules(s *S3Conf) error { + testName := "PutBucketOwnershipControls_empty_rules" + return actionHandler(s, testName, func(_ *s3.Client, bucket string) error { + body := []byte(``) + req, err := createSignedReq(http.MethodPut, s.endpoint, bucket+"?ownershipControls", s.awsID, s.awsSecret, "s3", s.awsRegion, "", body, time.Now(), map[string]string{ + "Content-Type": "application/xml", + }) + if err != nil { + return err + } + + resp, err := s.httpClient.Do(req) + if err != nil { + return err + } + + return checkHTTPResponseApiErr(resp, s3err.GetAPIError(s3err.ErrMalformedXML)) + }) +} + func PutBucketOwnershipControls_success(s *S3Conf) error { testName := "PutBucketOwnershipControls_success" return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error { diff --git a/tests/integration/group-tests.go b/tests/integration/group-tests.go index 0bd7254b..4ef10bd5 100644 --- a/tests/integration/group-tests.go +++ b/tests/integration/group-tests.go @@ -119,6 +119,7 @@ func TestPutBucketOwnershipControls(ts *TestState) { ts.Run(PutBucketOwnershipControls_non_existing_bucket) ts.Run(PutBucketOwnershipControls_multiple_rules) ts.Run(PutBucketOwnershipControls_invalid_ownership) + ts.Run(PutBucketOwnershipControls_empty_rules) ts.Run(PutBucketOwnershipControls_success) } @@ -1383,6 +1384,7 @@ func GetIntTests() IntTests { "PutBucketOwnershipControls_non_existing_bucket": PutBucketOwnershipControls_non_existing_bucket, "PutBucketOwnershipControls_multiple_rules": PutBucketOwnershipControls_multiple_rules, "PutBucketOwnershipControls_invalid_ownership": PutBucketOwnershipControls_invalid_ownership, + "PutBucketOwnershipControls_empty_rules": PutBucketOwnershipControls_empty_rules, "PutBucketOwnershipControls_success": PutBucketOwnershipControls_success, "GetBucketOwnershipControls_non_existing_bucket": GetBucketOwnershipControls_non_existing_bucket, "GetBucketOwnershipControls_default_ownership": GetBucketOwnershipControls_default_ownership,