1# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. 2# Licensed to PSF under a Contributor Agreement. 3"""Safely evaluate Python string literals without using eval().""" 4 5import re 6 7simple_escapes = { 8 'a': '\a', 9 'b': '\b', 10 'f': '\f', 11 'n': '\n', 12 'r': '\r', 13 't': '\t', 14 'v': '\v', 15 "'": "'", 16 '"': '"', 17 '\\': '\\' 18} 19 20 21def escape(m): 22 all, tail = m.group(0, 1) 23 assert all.startswith('\\') 24 esc = simple_escapes.get(tail) 25 if esc is not None: 26 return esc 27 if tail.startswith('x'): 28 hexes = tail[1:] 29 if len(hexes) < 2: 30 raise ValueError("invalid hex string escape ('\\%s')" % tail) 31 try: 32 i = int(hexes, 16) 33 except ValueError: 34 raise ValueError("invalid hex string escape ('\\%s')" % tail) from None 35 else: 36 try: 37 i = int(tail, 8) 38 except ValueError: 39 raise ValueError("invalid octal string escape ('\\%s')" % tail) from None 40 return chr(i) 41 42 43def evalString(s): 44 assert s.startswith("'") or s.startswith('"'), repr(s[:1]) 45 q = s[0] 46 if s[:3] == q * 3: 47 q = q * 3 48 assert s.endswith(q), repr(s[-len(q):]) 49 assert len(s) >= 2 * len(q) 50 s = s[len(q):-len(q)] 51 return re.sub(r"\\(\'|\"|\\|[abfnrtv]|x.{0,2}|[0-7]{1,3})", escape, s) 52 53 54def test(): 55 for i in range(256): 56 c = chr(i) 57 s = repr(c) 58 e = evalString(s) 59 if e != c: 60 print(i, c, s, e) 61 62 63if __name__ == '__main__': 64 test() 65