From da88aaa45664477e1aac7e4de56f7e78521903e0 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 10 Jan 2024 08:32:00 -0500 Subject: [PATCH 1/4] Add 'TestAccS3ObjectDataSource_leadingDotSlash'. --- .../service/s3/object_data_source_test.go | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/internal/service/s3/object_data_source_test.go b/internal/service/s3/object_data_source_test.go index fe1acf7e0687..f04e97c0efbd 100644 --- a/internal/service/s3/object_data_source_test.go +++ b/internal/service/s3/object_data_source_test.go @@ -376,6 +376,44 @@ func TestAccS3ObjectDataSource_singleSlashAsKey(t *testing.T) { }) } +func TestAccS3ObjectDataSource_leadingDotSlash(t *testing.T) { + ctx := acctest.Context(t) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_s3_object.test" + dataSourceName1 := "data.aws_s3_object.test1" + dataSourceName2 := "data.aws_s3_object.test2" + + resourceOnlyConf, conf := testAccObjectDataSourceConfig_leadingDotSlash(rName) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.S3EndpointID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + PreventPostDestroyRefresh: true, + Steps: []resource.TestStep{ + { // nosemgrep:ci.test-config-funcs-correct-form + Config: resourceOnlyConf, + }, + { // nosemgrep:ci.test-config-funcs-correct-form + Config: conf, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName1, "body", "yes"), + resource.TestCheckResourceAttr(dataSourceName1, "content_length", "3"), + resource.TestCheckResourceAttrPair(dataSourceName1, "content_type", resourceName, "content_type"), + resource.TestCheckResourceAttrPair(dataSourceName1, "etag", resourceName, "etag"), + resource.TestMatchResourceAttr(dataSourceName1, "last_modified", regexache.MustCompile(rfc1123RegexPattern)), + + resource.TestCheckResourceAttr(dataSourceName2, "body", "yes"), + resource.TestCheckResourceAttr(dataSourceName2, "content_length", "3"), + resource.TestCheckResourceAttrPair(dataSourceName2, "content_type", resourceName, "content_type"), + resource.TestCheckResourceAttrPair(dataSourceName2, "etag", resourceName, "etag"), + resource.TestMatchResourceAttr(dataSourceName2, "last_modified", regexache.MustCompile(rfc1123RegexPattern)), + ), + }, + }, + }) +} + func TestAccS3ObjectDataSource_checksumMode(t *testing.T) { ctx := acctest.Context(t) rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -809,6 +847,35 @@ data "aws_s3_object" "test" { `, rName) } +func testAccObjectDataSourceConfig_leadingDotSlash(rName string) (string, string) { + resources := fmt.Sprintf(` +resource "aws_s3_bucket" "test" { + bucket = %[1]q +} + +resource "aws_s3_object" "test" { + bucket = aws_s3_bucket.test.bucket + key = "./%[1]s-key" + content = "yes" + content_type = "text/plain" +} +`, rName) + + both := acctest.ConfigCompose(resources, fmt.Sprintf(` +data "aws_s3_object" "test1" { + bucket = aws_s3_bucket.test.bucket + key = "%[1]s-key" +} + +data "aws_s3_object" "test2" { + bucket = aws_s3_bucket.test.bucket + key = "/%[1]s-key" +} +`, rName)) + + return resources, both +} + func testAccObjectDataSourceConfig_checksumMode(rName string) string { return fmt.Sprintf(` resource "aws_s3_bucket" "test" { From 4f9bfd50652e2d0a87af44a6b37440b51a506794 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 10 Jan 2024 09:06:29 -0500 Subject: [PATCH 2/4] Add 'TestAccS3ObjectDataSource_leadingMultipleSlashes'. --- .../service/s3/object_data_source_test.go | 81 ++++++++++++++++++- 1 file changed, 80 insertions(+), 1 deletion(-) diff --git a/internal/service/s3/object_data_source_test.go b/internal/service/s3/object_data_source_test.go index f04e97c0efbd..a7f62eefc8b5 100644 --- a/internal/service/s3/object_data_source_test.go +++ b/internal/service/s3/object_data_source_test.go @@ -414,6 +414,51 @@ func TestAccS3ObjectDataSource_leadingDotSlash(t *testing.T) { }) } +func TestAccS3ObjectDataSource_leadingMultipleSlashes(t *testing.T) { + ctx := acctest.Context(t) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_s3_object.test" + dataSourceName1 := "data.aws_s3_object.test1" + dataSourceName2 := "data.aws_s3_object.test2" + dataSourceName3 := "data.aws_s3_object.test3" + + resourceOnlyConf, conf := testAccObjectDataSourceConfig_leadingMultipleSlashes(rName) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.S3EndpointID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + PreventPostDestroyRefresh: true, + Steps: []resource.TestStep{ + { // nosemgrep:ci.test-config-funcs-correct-form + Config: resourceOnlyConf, + }, + { // nosemgrep:ci.test-config-funcs-correct-form + Config: conf, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName1, "body", "yes"), + resource.TestCheckResourceAttr(dataSourceName1, "content_length", "3"), + resource.TestCheckResourceAttrPair(dataSourceName1, "content_type", resourceName, "content_type"), + resource.TestCheckResourceAttrPair(dataSourceName1, "etag", resourceName, "etag"), + resource.TestMatchResourceAttr(dataSourceName1, "last_modified", regexache.MustCompile(rfc1123RegexPattern)), + + resource.TestCheckResourceAttr(dataSourceName2, "body", "yes"), + resource.TestCheckResourceAttr(dataSourceName2, "content_length", "3"), + resource.TestCheckResourceAttrPair(dataSourceName2, "content_type", resourceName, "content_type"), + resource.TestCheckResourceAttrPair(dataSourceName2, "etag", resourceName, "etag"), + resource.TestMatchResourceAttr(dataSourceName2, "last_modified", regexache.MustCompile(rfc1123RegexPattern)), + + resource.TestCheckResourceAttr(dataSourceName3, "body", "yes"), + resource.TestCheckResourceAttr(dataSourceName3, "content_length", "3"), + resource.TestCheckResourceAttrPair(dataSourceName3, "content_type", resourceName, "content_type"), + resource.TestCheckResourceAttrPair(dataSourceName3, "etag", resourceName, "etag"), + resource.TestMatchResourceAttr(dataSourceName3, "last_modified", regexache.MustCompile(rfc1123RegexPattern)), + ), + }, + }, + }) +} + func TestAccS3ObjectDataSource_checksumMode(t *testing.T) { ctx := acctest.Context(t) rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -766,7 +811,7 @@ resource "aws_s3_bucket" "test" { resource "aws_s3_object" "test" { bucket = aws_s3_bucket.test.bucket - key = "//%[1]s-key" + key = "/%[1]s-key" content = "yes" content_type = "text/plain" } @@ -876,6 +921,40 @@ data "aws_s3_object" "test2" { return resources, both } +func testAccObjectDataSourceConfig_leadingMultipleSlashes(rName string) (string, string) { + resources := fmt.Sprintf(` +resource "aws_s3_bucket" "test" { + bucket = %[1]q +} + +resource "aws_s3_object" "test" { + bucket = aws_s3_bucket.test.bucket + key = "///%[1]s-key" + content = "yes" + content_type = "text/plain" +} +`, rName) + + both := acctest.ConfigCompose(resources, fmt.Sprintf(` +data "aws_s3_object" "test1" { + bucket = aws_s3_bucket.test.bucket + key = "%[1]s-key" +} + +data "aws_s3_object" "test2" { + bucket = aws_s3_bucket.test.bucket + key = "/%[1]s-key" +} + +data "aws_s3_object" "test3" { + bucket = aws_s3_bucket.test.bucket + key = "//%[1]s-key" +} +`, rName)) + + return resources, both +} + func testAccObjectDataSourceConfig_checksumMode(rName string) string { return fmt.Sprintf(` resource "aws_s3_bucket" "test" { From 918a868285245692740f1fd9f910b7d10dea2360 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 10 Jan 2024 09:22:03 -0500 Subject: [PATCH 3/4] Remove leading './' from S3 object key names for AWS SDK for Go v1 compatibility. --- internal/service/s3/object.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/service/s3/object.go b/internal/service/s3/object.go index c3723f0e8cae..ad5fdd8cbf78 100644 --- a/internal/service/s3/object.go +++ b/internal/service/s3/object.go @@ -733,6 +733,8 @@ func flattenObjectDate(t *time.Time) string { // See https://docs.aws.amazon.com/sdk-for-go/api/service/s3/#hdr-Automatic_URI_cleaning. // See https://github.com/aws/aws-sdk-go/blob/cf903c8c543034654bb8f53b5f9d6454fdb2117f/private/protocol/rest/build.go#L247-L258. func sdkv1CompatibleCleanKey(key string) string { + // Remove leading './'. + key = strings.TrimPrefix(key, "./") // We are effectively ignoring all leading '/'s and treating multiple '/'s as a single '/'. key = strings.TrimLeft(key, "/") key = regexache.MustCompile(`/+`).ReplaceAllString(key, "/") From 699b04f0d2c18d5af66148010a8b84a03897e0bb Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 10 Jan 2024 09:28:41 -0500 Subject: [PATCH 4/4] Add CHANGELOG entry. --- .changelog/35223.txt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .changelog/35223.txt diff --git a/.changelog/35223.txt b/.changelog/35223.txt new file mode 100644 index 000000000000..1196ccfee076 --- /dev/null +++ b/.changelog/35223.txt @@ -0,0 +1,19 @@ +```release-note:bug +resource/aws_s3_object: Remove any leading `./` from `key` to maintain AWS SDK for Go v1 (pre-v5.17.0) compatibility +``` + +```release-note:bug +data-source/aws_s3_object: Remove any leading `./` from `key` to maintain AWS SDK for Go v1 (pre-v5.17.0) compatibility +``` + +```release-note:bug +data-source/aws_s3_bucket_object: Remove any leading `./` from `key` to maintain AWS SDK for Go v1 (pre-v5.17.0) compatibility +``` + +```release-note:bug +resource/aws_s3_object_copy: Remove any leading `./` from `key` to maintain AWS SDK for Go v1 (pre-v5.17.0) compatibility +``` + +```release-note:bug +resource/aws_s3_bucket_object: Remove any leading `./` from `key` to maintain AWS SDK for Go v1 (pre-v5.17.0) compatibility +``` \ No newline at end of file