60 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			60 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| 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()
 | 
