Skip to content

Commit 8dbda8b

Browse files
authored
Port from PR #10044 argparse percent escaping fix to CLI v2 (#10067)
1 parent d7a5d64 commit 8dbda8b

2 files changed

Lines changed: 37 additions & 2 deletions

File tree

awscli/arguments.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,7 @@ def add_to_parser(self, parser):
449449
cli_name = self.cli_name
450450
parser.add_argument(
451451
cli_name,
452-
help=self.documentation,
452+
help=self.documentation.replace('%', '%%'),
453453
type=self.cli_type,
454454
required=self.required,
455455
)
@@ -600,7 +600,7 @@ def add_to_arg_table(self, argument_table):
600600
def add_to_parser(self, parser):
601601
parser.add_argument(
602602
self.cli_name,
603-
help=self.documentation,
603+
help=self.documentation.replace('%', '%%'),
604604
action=self._action,
605605
default=self._default,
606606
dest=self._destination,

tests/unit/test_argprocess.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
from awscli.help import OperationHelpCommand
3434
from awscli.paramfile import LOCAL_PREFIX_MAP, URIArgumentHandler
3535
from awscli.testutils import BaseCLIDriverTest, mock, temporary_file, unittest
36+
from awscli.argparser import ArgTableArgParser
3637

3738

3839
# These tests use real service types so that we can
@@ -968,5 +969,39 @@ def test_json_value_decode_error(self):
968969
unpack_cli_arg(self.p, value)
969970

970971

972+
class TestArgumentPercentEscaping(BaseArgProcessTest):
973+
def _test_percent_escaping(self, arg_type, arg_class, doc_string):
974+
argument = self.create_argument(
975+
{
976+
'Test': {
977+
'type': arg_type,
978+
'documentation': doc_string,
979+
}
980+
}
981+
)
982+
arg = arg_class(
983+
'test-arg',
984+
argument.argument_model.members['Test'],
985+
mock.Mock(),
986+
mock.Mock(),
987+
is_required=False,
988+
)
989+
arg_table = {arg.name: arg}
990+
parser = ArgTableArgParser(arg_table)
991+
help_output = parser.format_help()
992+
self.assertIn(doc_string, help_output)
993+
994+
def test_cli_argument_escapes_percent(self):
995+
self._test_percent_escaping('string', CLIArgument, 'Symbols: % ^ & *')
996+
997+
def test_boolean_argument_escapes_percent(self):
998+
self._test_percent_escaping('boolean', BooleanArgument, 'Symbols: % ^ & *')
999+
1000+
def test_cli_argument_escapes_url_encoded_percent(self):
1001+
self._test_percent_escaping('string', CLIArgument, 'File: test%28file%29.png')
1002+
1003+
def test_boolean_argument_escapes_url_encoded_percent(self):
1004+
self._test_percent_escaping('boolean', BooleanArgument, 'File: test%28file%29.png')
1005+
9711006
if __name__ == '__main__':
9721007
unittest.main()

0 commit comments

Comments
 (0)