diff --git a/pwndbg/commands/__init__.py b/pwndbg/commands/__init__.py index cfde47451..25ebffea1 100644 --- a/pwndbg/commands/__init__.py +++ b/pwndbg/commands/__init__.py @@ -123,6 +123,9 @@ class Command: def split_args(self, argument: str) -> Tuple[List[str], Dict[Any, Any]]: """Split a command-line string from the user into arguments. + This is only used by pwndbg/commands/shell.py which is deprecated. + Usually _ArgparsedCommand.split_args is called. + Returns: A ``(tuple, dict)``, in the form of ``*args, **kwargs``. The contents of the tuple/dict are undefined. @@ -139,6 +142,7 @@ class Command: args, kwargs = self.split_args(argument) except SystemExit: # Raised when the usage is printed by an ArgparsedCommand + # because of an error in argument parsing return except (TypeError, pwndbg.dbg_mod.Error): pwndbg.exception.handle(self.function.__name__) @@ -264,6 +268,18 @@ def fix_reraise(*a, **kw) -> str | pwndbg.dbg_mod.Value | None: return fix(*a, reraise=True, **kw) # type: ignore[misc] +def fix_reraise_arg(arg) -> pwndbg.dbg_mod.Value: + """fix_reraise wrapper for evaluating command arguments""" + try: + # Will always return pwndbg.dbg_mod.Value because + # sloppy=False (not str) and reraise=True (not None) + fixed = fix(arg, sloppy=False, quiet=True, reraise=True) + assert isinstance(fixed, pwndbg.dbg_mod.Value) + return fixed + except pwndbg.dbg_mod.Error as dbge: + raise argparse.ArgumentTypeError(f"debugger couldn't resolve argument '{arg}': {dbge}") + + def fix_int(*a, **kw) -> int: return int(fix(*a, **kw)) @@ -272,6 +288,17 @@ def fix_int_reraise(*a, **kw) -> int: return fix_int(*a, reraise=True, **kw) +def fix_int_reraise_arg(arg) -> int: + """fix_int_reraise wrapper for evaluating command arguments""" + try: + fixed = fix_reraise_arg(arg) + return int(fixed) + except pwndbg.dbg_mod.Error as e: + raise argparse.ArgumentTypeError( + f"couldn't convert '{arg}' ({fixed.type.name_to_human_readable}) to int: {e}" + ) + + def OnlyWhenLocal(function: Callable[P, T]) -> Callable[P, Optional[T]]: @functools.wraps(function) def _OnlyWhenLocal(*a: P.args, **kw: P.kwargs) -> Optional[T]: @@ -604,10 +631,10 @@ class ArgparsedCommand: action.type = str if action.dest == "help": continue - if action.type == int: - action.type = fix_int_reraise + if action.type is int: + action.type = fix_int_reraise_arg if action.type is None: - action.type = fix_reraise + action.type = fix_reraise_arg if action.default is not None: action.help += " (default: %(default)s)"