Skip to content

Commit 307cbe9

Browse files
authored
fix S3 copy-source format validation (#10338)
1 parent b0dea55 commit 307cbe9

File tree

4 files changed

+40
-3
lines changed

4 files changed

+40
-3
lines changed

localstack/services/s3/utils.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,15 @@ def extract_bucket_key_version_id_from_copy_source(
119119
copy_source_parsed = urlparser.urlparse(copy_source)
120120
# we need to manually replace `+` character with a space character before URL decoding, because different languages
121121
# don't encode their URL the same way (%20 vs +), and Python doesn't unquote + into a space char
122-
src_bucket, src_key = (
123-
urlparser.unquote(copy_source_parsed.path.replace("+", " ")).lstrip("/").split("/", 1)
124-
)
122+
parsed_path = urlparser.unquote(copy_source_parsed.path.replace("+", " ")).lstrip("/")
123+
124+
if "/" not in parsed_path:
125+
raise InvalidArgument(
126+
"Invalid copy source object key",
127+
ArgumentName="x-amz-copy-source",
128+
ArgumentValue="x-amz-copy-source",
129+
)
130+
src_bucket, src_key = parsed_path.split("/", 1)
125131
src_version_id = urlparser.parse_qs(copy_source_parsed.query).get("versionId", [None])[0]
126132

127133
return src_bucket, src_key, src_version_id

tests/aws/services/s3/test_s3.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1870,6 +1870,17 @@ def test_s3_copy_object_preconditions(self, s3_bucket, snapshot, aws_client):
18701870
)
18711871
snapshot.match("copy-success", copy_obj_all_positive)
18721872

1873+
@markers.aws.validated
1874+
def test_s3_copy_object_wrong_format(self, s3_bucket, snapshot, aws_client):
1875+
snapshot.add_transformer(snapshot.transform.s3_api())
1876+
with pytest.raises(ClientError) as e:
1877+
aws_client.s3.copy_object(
1878+
Bucket=s3_bucket,
1879+
CopySource="wrongformat",
1880+
Key="destination-key",
1881+
)
1882+
snapshot.match("copy-object-wrong-copy-source", e.value.response)
1883+
18731884
@markers.aws.validated
18741885
@pytest.mark.skipif(
18751886
condition=LEGACY_V2_S3_PROVIDER,

tests/aws/services/s3/test_s3.snapshot.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11210,5 +11210,22 @@
1121011210
}
1121111211
}
1121211212
}
11213+
},
11214+
"tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_wrong_format": {
11215+
"recorded-date": "27-02-2024, 11:11:22",
11216+
"recorded-content": {
11217+
"copy-object-wrong-copy-source": {
11218+
"Error": {
11219+
"ArgumentName": "x-amz-copy-source",
11220+
"ArgumentValue": "x-amz-copy-source",
11221+
"Code": "InvalidArgument",
11222+
"Message": "Invalid copy source object key"
11223+
},
11224+
"ResponseMetadata": {
11225+
"HTTPHeaders": {},
11226+
"HTTPStatusCode": 400
11227+
}
11228+
}
11229+
}
1121311230
}
1121411231
}

tests/aws/services/s3/test_s3.validation.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,9 @@
302302
"tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_with_checksum[SHA256]": {
303303
"last_validated_date": "2023-08-03T02:15:56+00:00"
304304
},
305+
"tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_object_wrong_format": {
306+
"last_validated_date": "2024-02-27T11:11:22+00:00"
307+
},
305308
"tests/aws/services/s3/test_s3.py::TestS3::test_s3_copy_tagging_directive[COPY]": {
306309
"last_validated_date": "2023-08-03T02:15:09+00:00"
307310
},

0 commit comments

Comments
 (0)