diff options
author | Tian Gao <gaogaotiantian@hotmail.com> | 2023-05-31 20:51:46 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-31 20:51:46 (GMT) |
commit | d944d873b2d7a627c20246762e931f9d4fcf8fe7 (patch) | |
tree | 308cdc00c7a065c65b52bae3ead9946ef2f3b185 /Lib/pdb.py | |
parent | ed86e14b1672f32f0a31d72070e93d361ee0e2b4 (diff) | |
download | cpython-d944d873b2d7a627c20246762e931f9d4fcf8fe7.zip cpython-d944d873b2d7a627c20246762e931f9d4fcf8fe7.tar.gz cpython-d944d873b2d7a627c20246762e931f9d4fcf8fe7.tar.bz2 |
gh-103464: Add checks for arguments of pdb commands (GH-103465)
Diffstat (limited to 'Lib/pdb.py')
-rwxr-xr-x | Lib/pdb.py | 64 |
1 files changed, 56 insertions, 8 deletions
@@ -644,7 +644,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): try: bnum = int(arg) except: - self.error("Usage: commands [bnum]\n ...\n end") + self._print_invalid_arg(arg) return try: self.get_bpbynumber(bnum) @@ -941,14 +941,22 @@ class Pdb(bdb.Bdb, cmd.Cmd): condition evaluates to true. """ args = arg.split() - try: - count = int(args[1].strip()) - except: + if not args: + self.error('Breakpoint number expected') + return + if len(args) == 1: count = 0 + elif len(args) == 2: + try: + count = int(args[1]) + except ValueError: + self._print_invalid_arg(arg) + return + else: + self._print_invalid_arg(arg) + return try: bp = self.get_bpbynumber(args[0].strip()) - except IndexError: - self.error('Breakpoint number expected') except ValueError as err: self.error(err) else: @@ -1025,6 +1033,9 @@ class Pdb(bdb.Bdb, cmd.Cmd): An arrow indicates the "current frame", which determines the context of most commands. 'bt' is an alias for this command. """ + if arg: + self._print_invalid_arg(arg) + return self.print_stack_trace() do_w = do_where do_bt = do_where @@ -1112,6 +1123,9 @@ class Pdb(bdb.Bdb, cmd.Cmd): (either in a function that is called or in the current function). """ + if arg: + self._print_invalid_arg(arg) + return self.set_step() return 1 do_s = do_step @@ -1122,6 +1136,9 @@ class Pdb(bdb.Bdb, cmd.Cmd): Continue execution until the next line in the current function is reached or it returns. """ + if arg: + self._print_invalid_arg(arg) + return self.set_next(self.curframe) return 1 do_n = do_next @@ -1153,6 +1170,9 @@ class Pdb(bdb.Bdb, cmd.Cmd): Continue execution until the current function returns. """ + if arg: + self._print_invalid_arg(arg) + return self.set_return(self.curframe) return 1 do_r = do_return @@ -1162,6 +1182,9 @@ class Pdb(bdb.Bdb, cmd.Cmd): Continue execution, only stop when a breakpoint is encountered. """ + if arg: + self._print_invalid_arg(arg) + return if not self.nosigint: try: Pdb._previous_sigint_handler = \ @@ -1256,6 +1279,9 @@ class Pdb(bdb.Bdb, cmd.Cmd): Print the argument list of the current function. """ + if arg: + self._print_invalid_arg(arg) + return co = self.curframe.f_code dict = self.curframe_locals n = co.co_argcount + co.co_kwonlyargcount @@ -1274,6 +1300,9 @@ class Pdb(bdb.Bdb, cmd.Cmd): Print the return value for the last return of a function. """ + if arg: + self._print_invalid_arg(arg) + return if '__return__' in self.curframe_locals: self.message(repr(self.curframe_locals['__return__'])) else: @@ -1390,6 +1419,9 @@ class Pdb(bdb.Bdb, cmd.Cmd): List the whole source code for the current function or frame. """ + if arg: + self._print_invalid_arg(arg) + return filename = self.curframe.f_code.co_filename breaklist = self.get_file_breaks(filename) try: @@ -1570,7 +1602,9 @@ class Pdb(bdb.Bdb, cmd.Cmd): Delete the specified alias. """ args = arg.split() - if len(args) == 0: return + if len(args) == 0: + self._print_invalid_arg(arg) + return if args[0] in self.aliases: del self.aliases[args[0]] @@ -1723,7 +1757,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): lineno = max(1, lineno) return lines, lineno - def _help_message_from_doc(self, doc): + def _help_message_from_doc(self, doc, usage_only=False): lines = [line.strip() for line in doc.rstrip().splitlines()] if not lines: return "No help message found." @@ -1739,10 +1773,24 @@ class Pdb(bdb.Bdb, cmd.Cmd): elif i < usage_end: prefix = " " else: + if usage_only: + break prefix = "" formatted.append(indent + prefix + line) return "\n".join(formatted) + def _print_invalid_arg(self, arg): + """Return the usage string for a function.""" + + self.error(f"Invalid argument: {arg}") + + # Yes it's a bit hacky. Get the caller name, get the method based on + # that name, and get the docstring from that method. + # This should NOT fail if the caller is a method of this class. + doc = inspect.getdoc(getattr(self, sys._getframe(1).f_code.co_name)) + if doc is not None: + self.message(self._help_message_from_doc(doc, usage_only=True)) + # Collect all command help into docstring, if not run with -OO if __doc__ is not None: |