Skip to content

Commit d78f3a4

Browse files
author
Kiro
committed
fix: validate stack name to prevent crash with special characters
1 parent 29ecb83 commit d78f3a4

3 files changed

Lines changed: 30 additions & 1 deletion

File tree

samcli/commands/deploy/deploy_context.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import logging
1919
import os
20+
import re
2021
from typing import Dict, List, Optional
2122

2223
import boto3
@@ -120,6 +121,9 @@ def run(self):
120121
Execute deployment based on the argument provided by customers and samconfig.toml.
121122
"""
122123

124+
if not re.match(r"^[a-zA-Z][-a-zA-Z0-9]*$", self.stack_name) or len(self.stack_name) > 128:
125+
raise deploy_exceptions.DeployInvalidStackNameError(stack_name=self.stack_name)
126+
123127
# Parse parameters
124128
with open(self.template_file, "r") as handle:
125129
template_str = handle.read()

samcli/commands/deploy/exceptions.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,16 @@ def parse_findmap_error(error_message: str) -> Optional[Tuple[str, str]]:
4343
return None
4444

4545

46+
class DeployInvalidStackNameError(UserException):
47+
def __init__(self, stack_name):
48+
self.stack_name = stack_name
49+
message_fmt = (
50+
"Invalid stack name '{stack_name}'. Stack names must start with a letter, "
51+
"contain only letters, numbers, and hyphens, and be at most 128 characters."
52+
)
53+
super().__init__(message=message_fmt.format(stack_name=self.stack_name))
54+
55+
4656
class ChangeEmptyError(UserException):
4757
def __init__(self, stack_name):
4858
self.stack_name = stack_name

tests/unit/commands/deploy/test_deploy_context.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
from samcli.lib.deploy.deployer import Deployer
88
from samcli.commands.deploy.deploy_context import DeployContext
9-
from samcli.commands.deploy.exceptions import DeployBucketRequiredError, DeployFailedError, ChangeEmptyError
9+
from samcli.commands.deploy.exceptions import DeployBucketRequiredError, DeployFailedError, ChangeEmptyError, DeployInvalidStackNameError
1010
from samcli.lib.deploy.utils import FailureMode
1111
from samcli.commands.deploy.exceptions import DeployFailedError
1212

@@ -41,6 +41,21 @@ def setUp(self):
4141
max_wait_duration=60,
4242
)
4343

44+
def test_invalid_stack_name_special_chars(self):
45+
self.deploy_command_context.stack_name = "my-stack@v2"
46+
with self.assertRaises(DeployInvalidStackNameError):
47+
self.deploy_command_context.run()
48+
49+
def test_invalid_stack_name_starts_with_digit(self):
50+
self.deploy_command_context.stack_name = "1stack"
51+
with self.assertRaises(DeployInvalidStackNameError):
52+
self.deploy_command_context.run()
53+
54+
def test_invalid_stack_name_too_long(self):
55+
self.deploy_command_context.stack_name = "a" * 129
56+
with self.assertRaises(DeployInvalidStackNameError):
57+
self.deploy_command_context.run()
58+
4459
@patch("boto3.client")
4560
@patch("boto3.Session")
4661
def test_template_improper(self, mock_session, mock_boto):

0 commit comments

Comments
 (0)