From 66c13ef982015a3843a717362b76316d0031fc53 Mon Sep 17 00:00:00 2001 From: jonaustin09 Date: Thu, 31 Oct 2024 17:05:54 -0400 Subject: [PATCH] fix: Adds a check to ensure the x-amz-object-attributes header is set and non-empty. --- s3api/utils/utils.go | 4 ++++ s3err/s3err.go | 6 ++++++ tests/integration/group-tests.go | 2 ++ tests/integration/tests.go | 24 ++++++++++++++++++++++++ 4 files changed, 36 insertions(+) diff --git a/s3api/utils/utils.go b/s3api/utils/utils.go index 6302ba8..17fd99f 100644 --- a/s3api/utils/utils.go +++ b/s3api/utils/utils.go @@ -294,6 +294,10 @@ func ParseObjectAttributes(ctx *fiber.Ctx) (map[s3response.ObjectAttributes]stru } }) + if len(attrs) == 0 { + return nil, s3err.GetAPIError(s3err.ErrObjectAttributesInvalidHeader) + } + return attrs, err } diff --git a/s3err/s3err.go b/s3err/s3err.go index 0a885be..3d19471 100644 --- a/s3err/s3err.go +++ b/s3err/s3err.go @@ -125,6 +125,7 @@ const ( ErrNoSuchBucketPolicy ErrBucketTaggingNotFound ErrObjectLockInvalidHeaders + ErrObjectAttributesInvalidHeader ErrRequestTimeTooSkewed ErrInvalidBucketAclWithObjectOwnership ErrBothCannedAndHeaderGrants @@ -505,6 +506,11 @@ var errorCodeResponse = map[ErrorCode]APIError{ Description: "x-amz-object-lock-retain-until-date and x-amz-object-lock-mode must both be supplied.", HTTPStatusCode: http.StatusBadRequest, }, + ErrObjectAttributesInvalidHeader: { + Code: "InvalidRequest", + Description: "The x-amz-object-attributes header specifying the attributes to be retrieved is either missing or empty", + HTTPStatusCode: http.StatusBadRequest, + }, ErrRequestTimeTooSkewed: { Code: "RequestTimeTooSkewed", Description: "The difference between the request time and the server's time is too large.", diff --git a/tests/integration/group-tests.go b/tests/integration/group-tests.go index 47ede0c..b4a80cb 100644 --- a/tests/integration/group-tests.go +++ b/tests/integration/group-tests.go @@ -158,6 +158,7 @@ func TestGetObjectAttributes(s *S3Conf) { GetObjectAttributes_non_existing_bucket(s) GetObjectAttributes_non_existing_object(s) GetObjectAttributes_invalid_attrs(s) + GetObjectAttributes_empty_attrs(s) GetObjectAttributes_existing_object(s) } @@ -726,6 +727,7 @@ func GetIntTests() IntTests { "GetObjectAttributes_non_existing_bucket": GetObjectAttributes_non_existing_bucket, "GetObjectAttributes_non_existing_object": GetObjectAttributes_non_existing_object, "GetObjectAttributes_invalid_attrs": GetObjectAttributes_invalid_attrs, + "GetObjectAttributes_empty_attrs": GetObjectAttributes_empty_attrs, "GetObjectAttributes_existing_object": GetObjectAttributes_existing_object, "GetObject_non_existing_key": GetObject_non_existing_key, "GetObject_directory_object_noslash": GetObject_directory_object_noslash, diff --git a/tests/integration/tests.go b/tests/integration/tests.go index 8ad971b..3451dfb 100644 --- a/tests/integration/tests.go +++ b/tests/integration/tests.go @@ -3417,6 +3417,30 @@ func GetObjectAttributes_invalid_attrs(s *S3Conf) error { }) } +func GetObjectAttributes_empty_attrs(s *S3Conf) error { + testName := "GetObjectAttributes_empty_attrs" + return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error { + obj := "my-obj" + _, err := putObjects(s3client, []string{obj}, bucket) + if err != nil { + return err + } + + ctx, cancel := context.WithTimeout(context.Background(), shortTimeout) + _, err = s3client.GetObjectAttributes(ctx, &s3.GetObjectAttributesInput{ + Bucket: &bucket, + Key: &obj, + ObjectAttributes: []types.ObjectAttributes{}, + }) + cancel() + if err := checkApiErr(err, s3err.GetAPIError(s3err.ErrObjectAttributesInvalidHeader)); err != nil { + return err + } + + return nil + }) +} + func GetObjectAttributes_existing_object(s *S3Conf) error { testName := "GetObjectAttributes_existing_object" return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {