| # Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. |
| # Licensed to PSF under a Contributor Agreement. |
| |
| """Safely evaluate Python string literals without using eval().""" |
| |
| import re |
| |
| simple_escapes = {"a": "\a", |
| "b": "\b", |
| "f": "\f", |
| "n": "\n", |
| "r": "\r", |
| "t": "\t", |
| "v": "\v", |
| "'": "'", |
| '"': '"', |
| "\\": "\\"} |
| |
| def escape(m): |
| all, tail = m.group(0, 1) |
| assert all.startswith("\\") |
| esc = simple_escapes.get(tail) |
| if esc is not None: |
| return esc |
| if tail.startswith("x"): |
| hexes = tail[1:] |
| if len(hexes) < 2: |
| raise ValueError("invalid hex string escape ('\\%s')" % tail) |
| try: |
| i = int(hexes, 16) |
| except ValueError: |
| raise ValueError("invalid hex string escape ('\\%s')" % tail) |
| else: |
| try: |
| i = int(tail, 8) |
| except ValueError: |
| raise ValueError("invalid octal string escape ('\\%s')" % tail) |
| return chr(i) |
| |
| def evalString(s): |
| assert s.startswith("'") or s.startswith('"'), repr(s[:1]) |
| q = s[0] |
| if s[:3] == q*3: |
| q = q*3 |
| assert s.endswith(q), repr(s[-len(q):]) |
| assert len(s) >= 2*len(q) |
| s = s[len(q):-len(q)] |
| return re.sub(r"\\(\'|\"|\\|[abfnrtv]|x.{0,2}|[0-7]{1,3})", escape, s) |
| |
| def test(): |
| for i in range(256): |
| c = chr(i) |
| s = repr(c) |
| e = evalString(s) |
| if e != c: |
| print(i, c, s, e) |
| |
| |
| if __name__ == "__main__": |
| test() |