Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion botocore/endpoint_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
TEMPLATE_STRING_RE = re.compile(r"\{[a-zA-Z#]+\}")
GET_ATTR_RE = re.compile(r"(\w*)\[(\d+)\]")
VALID_HOST_LABEL_RE = re.compile(
r"^(?!-)[a-zA-Z\d-]{1,63}(?<!-)$",
r"^(?!-)[a-zA-Z\d-]{1,63}(?<!-)\Z",
)
CACHE_SIZE = 100
# S3 endpoint ruleset parameters that are defined but not currently referenced.
Expand Down
2 changes: 1 addition & 1 deletion botocore/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1003,7 +1003,7 @@ def __call__(self, client, **kwargs):
class HeaderToHostHoister:
"""Takes a header and moves it to the front of the hoststring."""

_VALID_HOSTNAME = re.compile(r'(?!-)[a-z\d-]{1,63}(?<!-)$', re.IGNORECASE)
_VALID_HOSTNAME = re.compile(r'(?!-)[a-z\d-]{1,63}(?<!-)\Z', re.IGNORECASE)

def __init__(self, header_name):
self._header_name = header_name
Expand Down
2 changes: 1 addition & 1 deletion botocore/serialize.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
ISO8601 = '%Y-%m-%dT%H:%M:%SZ'
# Same as ISO8601, but with microsecond precision.
ISO8601_MICRO = '%Y-%m-%dT%H:%M:%S.%fZ'
HOST_PREFIX_RE = re.compile(r"^[A-Za-z0-9\.\-]+$")
HOST_PREFIX_RE = re.compile(r"^[A-Za-z0-9\.\-]+\Z")

TIMESTAMP_PRECISION_DEFAULT = 'default'
TIMESTAMP_PRECISION_MILLISECOND = 'millisecond'
Expand Down
6 changes: 4 additions & 2 deletions botocore/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -1335,7 +1335,9 @@ def validate_region_name(region_name):
"""Provided region_name must be a valid host label."""
if region_name is None:
return
valid_host_label = re.compile(r'^(?![0-9]+$)(?!-)[a-zA-Z0-9-]{,63}(?<!-)$')
valid_host_label = re.compile(
r'^(?![0-9]+$)(?!-)[a-zA-Z0-9-]{,63}(?<!-)\Z'
)
valid = valid_host_label.match(region_name)
if not valid:
raise InvalidRegionError(region_name=region_name)
Expand Down Expand Up @@ -2644,7 +2646,7 @@ def _s3_addressing_handler(self):
class S3ControlEndpointSetter:
_DEFAULT_PARTITION = 'aws'
_DEFAULT_DNS_SUFFIX = 'amazonaws.com'
_HOST_LABEL_REGEX = re.compile(r'^[a-zA-Z0-9\-]{1,63}$')
_HOST_LABEL_REGEX = re.compile(r'^[a-zA-Z0-9\-]{1,63}\Z')

def __init__(
self,
Expand Down
13 changes: 13 additions & 0 deletions tests/unit/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2207,6 +2207,19 @@ def test_get_region_validates_region_from_head_bucket(self):
with self.assertRaises(InvalidRegionError):
self.redirector.get_bucket_region('foo', response)

def test_get_region_rejects_region_with_trailing_newline(self):
response = (
None,
{
'Error': {'Code': 'PermanentRedirect'},
'ResponseMetadata': {
'HTTPHeaders': {'x-amz-bucket-region': 'us-west-2\n'}
},
},
)
with self.assertRaises(InvalidRegionError):
self.redirector.get_bucket_region('foo', response)


class TestArnParser(unittest.TestCase):
def setUp(self):
Expand Down