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