mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
gh-111719: Add extra check for alias command (#111720)
This commit is contained in:
parent
a6c1c04d4d
commit
853b4b549d
4 changed files with 51 additions and 7 deletions
|
@ -580,7 +580,7 @@ can be overridden by the local file.
|
|||
|
||||
Create an alias called *name* that executes *command*. The *command* must
|
||||
*not* be enclosed in quotes. Replaceable parameters can be indicated by
|
||||
``%1``, ``%2``, and so on, while ``%*`` is replaced by all the parameters.
|
||||
``%1``, ``%2``, ... and ``%9``, while ``%*`` is replaced by all the parameters.
|
||||
If *command* is omitted, the current alias for *name* is shown. If no
|
||||
arguments are given, all aliases are listed.
|
||||
|
||||
|
|
33
Lib/pdb.py
33
Lib/pdb.py
|
@ -597,11 +597,20 @@ class Pdb(bdb.Bdb, cmd.Cmd):
|
|||
args = line.split()
|
||||
while args[0] in self.aliases:
|
||||
line = self.aliases[args[0]]
|
||||
ii = 1
|
||||
for tmpArg in args[1:]:
|
||||
line = line.replace("%" + str(ii),
|
||||
tmpArg)
|
||||
ii += 1
|
||||
for idx in range(1, 10):
|
||||
if f'%{idx}' in line:
|
||||
if idx >= len(args):
|
||||
self.error(f"Not enough arguments for alias '{args[0]}'")
|
||||
# This is a no-op
|
||||
return "!"
|
||||
line = line.replace(f'%{idx}', args[idx])
|
||||
elif '%*' not in line:
|
||||
if idx < len(args):
|
||||
self.error(f"Too many arguments for alias '{args[0]}'")
|
||||
# This is a no-op
|
||||
return "!"
|
||||
break
|
||||
|
||||
line = line.replace("%*", ' '.join(args[1:]))
|
||||
args = line.split()
|
||||
# split into ';;' separated commands
|
||||
|
@ -616,6 +625,7 @@ class Pdb(bdb.Bdb, cmd.Cmd):
|
|||
|
||||
# Replace all the convenience variables
|
||||
line = re.sub(r'\$([a-zA-Z_][a-zA-Z0-9_]*)', r'__pdb_convenience_variables["\1"]', line)
|
||||
|
||||
return line
|
||||
|
||||
def onecmd(self, line):
|
||||
|
@ -1797,7 +1807,18 @@ class Pdb(bdb.Bdb, cmd.Cmd):
|
|||
else:
|
||||
self.error(f"Unknown alias '{args[0]}'")
|
||||
else:
|
||||
self.aliases[args[0]] = ' '.join(args[1:])
|
||||
# Do a validation check to make sure no replaceable parameters
|
||||
# are skipped if %* is not used.
|
||||
alias = ' '.join(args[1:])
|
||||
if '%*' not in alias:
|
||||
consecutive = True
|
||||
for idx in range(1, 10):
|
||||
if f'%{idx}' not in alias:
|
||||
consecutive = False
|
||||
if f'%{idx}' in alias and not consecutive:
|
||||
self.error("Replaceable parameters must be consecutive")
|
||||
return
|
||||
self.aliases[args[0]] = alias
|
||||
|
||||
def do_unalias(self, arg):
|
||||
"""unalias name
|
||||
|
|
|
@ -671,6 +671,14 @@ def test_pdb_alias_command():
|
|||
... 'pi o',
|
||||
... 's',
|
||||
... 'ps',
|
||||
... 'alias myp p %2',
|
||||
... 'alias myp',
|
||||
... 'alias myp p %1',
|
||||
... 'myp',
|
||||
... 'myp 1',
|
||||
... 'myp 1 2',
|
||||
... 'alias repeat_second_arg p "%* %2"',
|
||||
... 'repeat_second_arg 1 2 3',
|
||||
... 'continue',
|
||||
... ]):
|
||||
... test_function()
|
||||
|
@ -692,6 +700,20 @@ def test_pdb_alias_command():
|
|||
(Pdb) ps
|
||||
self.attr1 = 10
|
||||
self.attr2 = str
|
||||
(Pdb) alias myp p %2
|
||||
*** Replaceable parameters must be consecutive
|
||||
(Pdb) alias myp
|
||||
*** Unknown alias 'myp'
|
||||
(Pdb) alias myp p %1
|
||||
(Pdb) myp
|
||||
*** Not enough arguments for alias 'myp'
|
||||
(Pdb) myp 1
|
||||
1
|
||||
(Pdb) myp 1 2
|
||||
*** Too many arguments for alias 'myp'
|
||||
(Pdb) alias repeat_second_arg p "%* %2"
|
||||
(Pdb) repeat_second_arg 1 2 3
|
||||
'1 2 3 2'
|
||||
(Pdb) continue
|
||||
"""
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Add extra argument validation for ``alias`` command in :mod:`pdb`
|
Loading…
Add table
Add a link
Reference in a new issue