1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859 |
- import sys
- import os
- import re
- class DecodeError(ValueError):
- pass
- ESCAPE_RE = re.compile(br'--|-([A-F0-9]{2})')
- def decode_part(part):
- if not re.match(r'^[a-zA-Z0-9._-]*$', part):
- raise DecodeError('illegal characters found')
- part = part.encode('ascii')
- # Check if no '-' remains outside of legal escape sequences.
- if b'-' in ESCAPE_RE.sub(b'', part):
- raise DecodeError("'-' can be used only in '-HH' or '--'")
- def convert(m):
- if m.group(0) == b'--':
- return b'-'
- num = int(m.group(1), 16)
- return bytes([num])
- return ESCAPE_RE.sub(convert, part)
- def decode(arg):
- '''
- Decode the argument for executing. The format is as follows:
- - individual parts are split by '+'
- - bytes are escaped as '-HH' (where HH is hex code, capital letters only)
- - literal '-' is encoded as '--'
- - otherwise, only [a-zA-Z0-9._] are allowed
- :param arg: argument, as a string
- :returns: list of exec arguments (each as bytes)
- '''
- return [decode_part(part) for part in arg.split('+')]
- def main(argv=sys.argv):
- if len(argv) != 2:
- print('This service requires exactly one argument', file=sys.stderr)
- exit(1)
- try:
- command = decode(argv[1])
- except DecodeError as e:
- print('Decode error: {}'.format(e), file=sys.stderr)
- exit(1)
- os.execvp(command[0], command)
- if __name__ == '__main__':
- main()
|