17db96d56Sopenharmony_ci# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. 27db96d56Sopenharmony_ci# Licensed to PSF under a Contributor Agreement. 37db96d56Sopenharmony_ci 47db96d56Sopenharmony_ci"""Safely evaluate Python string literals without using eval().""" 57db96d56Sopenharmony_ci 67db96d56Sopenharmony_ciimport re 77db96d56Sopenharmony_ci 87db96d56Sopenharmony_cisimple_escapes = {"a": "\a", 97db96d56Sopenharmony_ci "b": "\b", 107db96d56Sopenharmony_ci "f": "\f", 117db96d56Sopenharmony_ci "n": "\n", 127db96d56Sopenharmony_ci "r": "\r", 137db96d56Sopenharmony_ci "t": "\t", 147db96d56Sopenharmony_ci "v": "\v", 157db96d56Sopenharmony_ci "'": "'", 167db96d56Sopenharmony_ci '"': '"', 177db96d56Sopenharmony_ci "\\": "\\"} 187db96d56Sopenharmony_ci 197db96d56Sopenharmony_cidef escape(m): 207db96d56Sopenharmony_ci all, tail = m.group(0, 1) 217db96d56Sopenharmony_ci assert all.startswith("\\") 227db96d56Sopenharmony_ci esc = simple_escapes.get(tail) 237db96d56Sopenharmony_ci if esc is not None: 247db96d56Sopenharmony_ci return esc 257db96d56Sopenharmony_ci if tail.startswith("x"): 267db96d56Sopenharmony_ci hexes = tail[1:] 277db96d56Sopenharmony_ci if len(hexes) < 2: 287db96d56Sopenharmony_ci raise ValueError("invalid hex string escape ('\\%s')" % tail) 297db96d56Sopenharmony_ci try: 307db96d56Sopenharmony_ci i = int(hexes, 16) 317db96d56Sopenharmony_ci except ValueError: 327db96d56Sopenharmony_ci raise ValueError("invalid hex string escape ('\\%s')" % tail) from None 337db96d56Sopenharmony_ci else: 347db96d56Sopenharmony_ci try: 357db96d56Sopenharmony_ci i = int(tail, 8) 367db96d56Sopenharmony_ci except ValueError: 377db96d56Sopenharmony_ci raise ValueError("invalid octal string escape ('\\%s')" % tail) from None 387db96d56Sopenharmony_ci return chr(i) 397db96d56Sopenharmony_ci 407db96d56Sopenharmony_cidef evalString(s): 417db96d56Sopenharmony_ci assert s.startswith("'") or s.startswith('"'), repr(s[:1]) 427db96d56Sopenharmony_ci q = s[0] 437db96d56Sopenharmony_ci if s[:3] == q*3: 447db96d56Sopenharmony_ci q = q*3 457db96d56Sopenharmony_ci assert s.endswith(q), repr(s[-len(q):]) 467db96d56Sopenharmony_ci assert len(s) >= 2*len(q) 477db96d56Sopenharmony_ci s = s[len(q):-len(q)] 487db96d56Sopenharmony_ci return re.sub(r"\\(\'|\"|\\|[abfnrtv]|x.{0,2}|[0-7]{1,3})", escape, s) 497db96d56Sopenharmony_ci 507db96d56Sopenharmony_cidef test(): 517db96d56Sopenharmony_ci for i in range(256): 527db96d56Sopenharmony_ci c = chr(i) 537db96d56Sopenharmony_ci s = repr(c) 547db96d56Sopenharmony_ci e = evalString(s) 557db96d56Sopenharmony_ci if e != c: 567db96d56Sopenharmony_ci print(i, c, s, e) 577db96d56Sopenharmony_ci 587db96d56Sopenharmony_ci 597db96d56Sopenharmony_ciif __name__ == "__main__": 607db96d56Sopenharmony_ci test() 61