Skip to content

Commit

Permalink
Fix registering commandline subparsers multiple times for Python 3.11
Browse files Browse the repository at this point in the history
Python 3.11 added a sanity check to argparse to prevent registering the same subparser multiple times.

argparse.ArgumentError: argument command: conflicting subparser: cyclic

Avoid importing the command twice.
`python -m pwnlib.commandline.cyclic` failed on Python 3.11 triggered in CI when running the commandline tools while collecting coverage.
  • Loading branch information
peace-maker committed Oct 11, 2024
1 parent 2d46f5a commit d931461
Show file tree
Hide file tree
Showing 22 changed files with 35 additions and 33 deletions.
2 changes: 1 addition & 1 deletion pwnlib/commandline/asm.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,4 +137,4 @@ def main(args):
args.output.write(b'\n')

if __name__ == '__main__':
pwnlib.commandline.common.main(__file__)
pwnlib.commandline.common.main(__file__, main)
2 changes: 1 addition & 1 deletion pwnlib/commandline/checksec.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,4 @@ def main(args):
e = ELF(f.name)

if __name__ == '__main__':
common.main(__file__)
common.main(__file__, main)
16 changes: 13 additions & 3 deletions pwnlib/commandline/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,18 @@ def context_arg(arg):
prog='pwn')
parser_commands = parser.add_subparsers(dest='command')

def main(file=sys.argv[0]):
import pwnlib.commandline.main
def main(file=sys.argv[0], command_main=None):
name = os.path.splitext(os.path.basename(file))[0]
if command_main is None:
import importlib
command_main = importlib.import_module('pwnlib.commandline.%s' % name).main
sys.argv.insert(1, name)
pwnlib.commandline.main.main()
entrypoint({name: command_main})

def entrypoint(commands):
if len(sys.argv) < 2:
parser.print_usage()
sys.exit()
args = parser.parse_args()
with context.local(log_console = sys.stderr):
commands[args.command](args)
2 changes: 1 addition & 1 deletion pwnlib/commandline/constgrep.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,4 +133,4 @@ def main(args):
print('(%s) == %s' % (' | '.join(k for v, k in good), args.constant))

if __name__ == '__main__':
pwnlib.commandline.common.main(__file__)
pwnlib.commandline.common.main(__file__, main)
2 changes: 1 addition & 1 deletion pwnlib/commandline/cyclic.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,4 @@ def main(args):
out.write(b'\n')

if __name__ == '__main__':
pwnlib.commandline.common.main(__file__)
pwnlib.commandline.common.main(__file__, main)
2 changes: 1 addition & 1 deletion pwnlib/commandline/debug.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,4 @@ def main(args):
gdb.debug(target, gdbscript=gdbscript, sysroot=args.sysroot).interactive()

if __name__ == '__main__':
pwnlib.commandline.common.main(__file__)
pwnlib.commandline.common.main(__file__, main)
2 changes: 1 addition & 1 deletion pwnlib/commandline/disablenx.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ def main(args):
ELF(e.path)

if __name__ == '__main__':
pwnlib.commandline.common.main(__file__)
pwnlib.commandline.common.main(__file__, main)
2 changes: 1 addition & 1 deletion pwnlib/commandline/disasm.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,4 @@ def main(args):
print(disasm(dat, vma=safeeval.const(args.address)))

if __name__ == '__main__':
pwnlib.commandline.common.main(__file__)
pwnlib.commandline.common.main(__file__, main)
2 changes: 1 addition & 1 deletion pwnlib/commandline/elfdiff.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,4 @@ def main(a):
print(diff(x, y))

if __name__ == '__main__':
pwnlib.commandline.common.main(__file__)
pwnlib.commandline.common.main(__file__, main)
2 changes: 1 addition & 1 deletion pwnlib/commandline/elfpatch.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,4 @@ def main(a):
getattr(sys.stdout, 'buffer', sys.stdout).write(elf.get_data())

if __name__ == '__main__':
pwnlib.commandline.common.main(__file__)
pwnlib.commandline.common.main(__file__, main)
2 changes: 1 addition & 1 deletion pwnlib/commandline/errno.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,4 @@ def main(args):
print(os.strerror(value))

if __name__ == '__main__':
common.main(__file__)
common.main(__file__, main)
2 changes: 1 addition & 1 deletion pwnlib/commandline/hex.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,4 @@ def main(args):
print(encoded)

if __name__ == '__main__':
common.main(__file__)
common.main(__file__, main)
2 changes: 1 addition & 1 deletion pwnlib/commandline/libcdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,4 +248,4 @@ def main(args):
log.indented('%25s = %#x', symbol, translate_offset(exe.symbols[symbol], args, exe))

if __name__ == '__main__':
pwnlib.commandline.common.main(__file__)
pwnlib.commandline.common.main(__file__, main)
12 changes: 2 additions & 10 deletions pwnlib/commandline/main.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
from __future__ import absolute_import

import sys

from pwnlib.commandline import asm
from pwnlib.commandline import checksec
from pwnlib.commandline import common
Expand All @@ -23,8 +21,7 @@
from pwnlib.commandline import unhex
from pwnlib.commandline import update
from pwnlib.commandline import version
from pwnlib.commandline.common import parser
from pwnlib.context import context
from pwnlib.commandline.common import parser as parser

commands = {
'asm': asm.main,
Expand All @@ -50,12 +47,7 @@
}

def main():
if len(sys.argv) < 2:
parser.print_usage()
sys.exit()
args = parser.parse_args()
with context.local(log_console = sys.stderr):
commands[args.command](args)
common.entrypoint(commands)

if __name__ == '__main__':
main()
2 changes: 1 addition & 1 deletion pwnlib/commandline/phd.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,4 @@ def main(args):
pass

if __name__ == '__main__':
pwnlib.commandline.common.main(__file__)
pwnlib.commandline.common.main(__file__, main)
2 changes: 1 addition & 1 deletion pwnlib/commandline/pwnstrip.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,4 @@ def main(args):
args.output.write(result)

if __name__ == '__main__':
pwnlib.commandline.common.main(__file__)
pwnlib.commandline.common.main(__file__, main)
2 changes: 1 addition & 1 deletion pwnlib/commandline/scramble.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,4 @@ def main(args):


if __name__ == '__main__':
pwnlib.commandline.common.main(__file__)
pwnlib.commandline.common.main(__file__, main)
2 changes: 1 addition & 1 deletion pwnlib/commandline/shellcraft.py
Original file line number Diff line number Diff line change
Expand Up @@ -352,4 +352,4 @@ def main(args):
args.out.write(code)

if __name__ == '__main__':
pwnlib.commandline.common.main(__file__)
pwnlib.commandline.common.main(__file__, main)
2 changes: 1 addition & 1 deletion pwnlib/commandline/template.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,5 +122,5 @@ def main(args):
except OSError: pass

if __name__ == '__main__':
pwnlib.commandline.common.main(__file__)
pwnlib.commandline.common.main(__file__, main)

2 changes: 1 addition & 1 deletion pwnlib/commandline/unhex.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@ def main(args):
raise

if __name__ == '__main__':
common.main(__file__)
common.main(__file__, main)
2 changes: 1 addition & 1 deletion pwnlib/commandline/update.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@ def main(a):
subprocess.check_call(result, shell=False)

if __name__ == '__main__':
pwnlib.commandline.common.main(__file__)
pwnlib.commandline.common.main(__file__, main)
2 changes: 1 addition & 1 deletion pwnlib/commandline/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ def main(a):
log.info("Pwntools v%s" % version)

if __name__ == '__main__':
pwnlib.commandline.common.main(__file__)
pwnlib.commandline.common.main(__file__, main)

0 comments on commit d931461

Please sign in to comment.