Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd944d87

Browse files
gh-103464: Add checks for arguments of pdb commands (GH-103465)
1 parented86e14 commitd944d87

File tree

3 files changed

+90
-11
lines changed

3 files changed

+90
-11
lines changed

‎Lib/pdb.py‎

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -644,7 +644,7 @@ def do_commands(self, arg):
644644
try:
645645
bnum=int(arg)
646646
except:
647-
self.error("Usage: commands [bnum]\n ...\n end")
647+
self._print_invalid_arg(arg)
648648
return
649649
try:
650650
self.get_bpbynumber(bnum)
@@ -941,14 +941,22 @@ def do_ignore(self, arg):
941941
condition evaluates to true.
942942
"""
943943
args=arg.split()
944-
try:
945-
count=int(args[1].strip())
946-
except:
944+
ifnotargs:
945+
self.error('Breakpoint number expected')
946+
return
947+
iflen(args)==1:
947948
count=0
949+
eliflen(args)==2:
950+
try:
951+
count=int(args[1])
952+
exceptValueError:
953+
self._print_invalid_arg(arg)
954+
return
955+
else:
956+
self._print_invalid_arg(arg)
957+
return
948958
try:
949959
bp=self.get_bpbynumber(args[0].strip())
950-
exceptIndexError:
951-
self.error('Breakpoint number expected')
952960
exceptValueErroraserr:
953961
self.error(err)
954962
else:
@@ -1025,6 +1033,9 @@ def do_where(self, arg):
10251033
An arrow indicates the "current frame", which determines the
10261034
context of most commands. 'bt' is an alias for this command.
10271035
"""
1036+
ifarg:
1037+
self._print_invalid_arg(arg)
1038+
return
10281039
self.print_stack_trace()
10291040
do_w=do_where
10301041
do_bt=do_where
@@ -1112,6 +1123,9 @@ def do_step(self, arg):
11121123
(either in a function that is called or in the current
11131124
function).
11141125
"""
1126+
ifarg:
1127+
self._print_invalid_arg(arg)
1128+
return
11151129
self.set_step()
11161130
return1
11171131
do_s=do_step
@@ -1122,6 +1136,9 @@ def do_next(self, arg):
11221136
Continue execution until the next line in the current function
11231137
is reached or it returns.
11241138
"""
1139+
ifarg:
1140+
self._print_invalid_arg(arg)
1141+
return
11251142
self.set_next(self.curframe)
11261143
return1
11271144
do_n=do_next
@@ -1153,6 +1170,9 @@ def do_return(self, arg):
11531170
11541171
Continue execution until the current function returns.
11551172
"""
1173+
ifarg:
1174+
self._print_invalid_arg(arg)
1175+
return
11561176
self.set_return(self.curframe)
11571177
return1
11581178
do_r=do_return
@@ -1162,6 +1182,9 @@ def do_continue(self, arg):
11621182
11631183
Continue execution, only stop when a breakpoint is encountered.
11641184
"""
1185+
ifarg:
1186+
self._print_invalid_arg(arg)
1187+
return
11651188
ifnotself.nosigint:
11661189
try:
11671190
Pdb._previous_sigint_handler= \
@@ -1256,6 +1279,9 @@ def do_args(self, arg):
12561279
12571280
Print the argument list of the current function.
12581281
"""
1282+
ifarg:
1283+
self._print_invalid_arg(arg)
1284+
return
12591285
co=self.curframe.f_code
12601286
dict=self.curframe_locals
12611287
n=co.co_argcount+co.co_kwonlyargcount
@@ -1274,6 +1300,9 @@ def do_retval(self, arg):
12741300
12751301
Print the return value for the last return of a function.
12761302
"""
1303+
ifarg:
1304+
self._print_invalid_arg(arg)
1305+
return
12771306
if'__return__'inself.curframe_locals:
12781307
self.message(repr(self.curframe_locals['__return__']))
12791308
else:
@@ -1390,6 +1419,9 @@ def do_longlist(self, arg):
13901419
13911420
List the whole source code for the current function or frame.
13921421
"""
1422+
ifarg:
1423+
self._print_invalid_arg(arg)
1424+
return
13931425
filename=self.curframe.f_code.co_filename
13941426
breaklist=self.get_file_breaks(filename)
13951427
try:
@@ -1570,7 +1602,9 @@ def do_unalias(self, arg):
15701602
Delete the specified alias.
15711603
"""
15721604
args=arg.split()
1573-
iflen(args)==0:return
1605+
iflen(args)==0:
1606+
self._print_invalid_arg(arg)
1607+
return
15741608
ifargs[0]inself.aliases:
15751609
delself.aliases[args[0]]
15761610

@@ -1723,7 +1757,7 @@ def _getsourcelines(self, obj):
17231757
lineno=max(1,lineno)
17241758
returnlines,lineno
17251759

1726-
def_help_message_from_doc(self,doc):
1760+
def_help_message_from_doc(self,doc,usage_only=False):
17271761
lines= [line.strip()forlineindoc.rstrip().splitlines()]
17281762
ifnotlines:
17291763
return"No help message found."
@@ -1739,10 +1773,24 @@ def _help_message_from_doc(self, doc):
17391773
elifi<usage_end:
17401774
prefix=" "
17411775
else:
1776+
ifusage_only:
1777+
break
17421778
prefix=""
17431779
formatted.append(indent+prefix+line)
17441780
return"\n".join(formatted)
17451781

1782+
def_print_invalid_arg(self,arg):
1783+
"""Return the usage string for a function."""
1784+
1785+
self.error(f"Invalid argument:{arg}")
1786+
1787+
# Yes it's a bit hacky. Get the caller name, get the method based on
1788+
# that name, and get the docstring from that method.
1789+
# This should NOT fail if the caller is a method of this class.
1790+
doc=inspect.getdoc(getattr(self,sys._getframe(1).f_code.co_name))
1791+
ifdocisnotNone:
1792+
self.message(self._help_message_from_doc(doc,usage_only=True))
1793+
17461794
# Collect all command help into docstring, if not run with -OO
17471795

17481796
if__doc__isnotNone:

‎Lib/test/test_pdb.py‎

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -334,9 +334,11 @@ def test_pdb_breakpoint_commands():
334334
(Pdb) commands 10
335335
*** cannot set commands: Breakpoint number 10 out of range
336336
(Pdb) commands a
337-
*** Usage: commands [bnum]
338-
...
339-
end
337+
*** Invalid argument: a
338+
Usage: (Pdb) commands [bpnumber]
339+
(com) ...
340+
(com) end
341+
(Pdb)
340342
(Pdb) commands 4
341343
*** cannot set commands: Breakpoint 4 already deleted
342344
(Pdb) break 6, undefined
@@ -908,6 +910,34 @@ def test_pdb_skip_modules():
908910
(Pdb) continue
909911
"""
910912

913+
deftest_pdb_invalid_arg():
914+
"""This tests pdb commands that have invalid arguments
915+
916+
>>> def test_function():
917+
... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
918+
... pass
919+
920+
>>> with PdbTestInput([
921+
... 'a = 3',
922+
... 'll 4',
923+
... 'step 1',
924+
... 'continue'
925+
... ]):
926+
... test_function()
927+
> <doctest test.test_pdb.test_pdb_invalid_arg[0]>(3)test_function()
928+
-> pass
929+
(Pdb) a = 3
930+
*** Invalid argument: = 3
931+
Usage: a(rgs)
932+
(Pdb) ll 4
933+
*** Invalid argument: 4
934+
Usage: ll | longlist
935+
(Pdb) step 1
936+
*** Invalid argument: 1
937+
Usage: s(tep)
938+
(Pdb) continue
939+
"""
940+
911941

912942
# Module for testing skipping of module that makes a callback
913943
mod=types.ModuleType('module_to_skip')
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Provide helpful usage messages when parsing incorrect:mod:`pdb` commands.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp