literals.py 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  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. import re
  5. simple_escapes = {"a": "\a",
  6. "b": "\b",
  7. "f": "\f",
  8. "n": "\n",
  9. "r": "\r",
  10. "t": "\t",
  11. "v": "\v",
  12. "'": "'",
  13. '"': '"',
  14. "\\": "\\"}
  15. def escape(m):
  16. all, tail = m.group(0, 1)
  17. assert all.startswith("\\")
  18. esc = simple_escapes.get(tail)
  19. if esc is not None:
  20. return esc
  21. if tail.startswith("x"):
  22. hexes = tail[1:]
  23. if len(hexes) < 2:
  24. raise ValueError("invalid hex string escape ('\\%s')" % tail)
  25. try:
  26. i = int(hexes, 16)
  27. except ValueError:
  28. raise ValueError("invalid hex string escape ('\\%s')" % tail) from None
  29. else:
  30. try:
  31. i = int(tail, 8)
  32. except ValueError:
  33. raise ValueError("invalid octal string escape ('\\%s')" % tail) from None
  34. return chr(i)
  35. def evalString(s):
  36. assert s.startswith("'") or s.startswith('"'), repr(s[:1])
  37. q = s[0]
  38. if s[:3] == q*3:
  39. q = q*3
  40. assert s.endswith(q), repr(s[-len(q):])
  41. assert len(s) >= 2*len(q)
  42. s = s[len(q):-len(q)]
  43. return re.sub(r"\\(\'|\"|\\|[abfnrtv]|x.{0,2}|[0-7]{1,3})", escape, s)
  44. def test():
  45. for i in range(256):
  46. c = chr(i)
  47. s = repr(c)
  48. e = evalString(s)
  49. if e != c:
  50. print(i, c, s, e)
  51. if __name__ == "__main__":
  52. test()