comparison mercurial/utils/stringutil.py @ 37476:e9dea82ea1f3

wireproto: convert python literal to object without using unsafe eval() Follows up cc5a040fe150. At this point, I don't think we need a real eval(). If we want to support a set literal, maybe we can vendor ast.literal_eval(), which is relatively simple function.
author Yuya Nishihara <yuya@tcha.org>
date Sun, 08 Apr 2018 11:55:46 +0900
parents a67fd1fe5109
children 68132a95df31
comparison
equal deleted inserted replaced
37475:152f1b47e0ad 37476:e9dea82ea1f3
7 # This software may be used and distributed according to the terms of the 7 # This software may be used and distributed according to the terms of the
8 # GNU General Public License version 2 or any later version. 8 # GNU General Public License version 2 or any later version.
9 9
10 from __future__ import absolute_import 10 from __future__ import absolute_import
11 11
12 import __future__ 12 import ast
13 import codecs 13 import codecs
14 import re as remod 14 import re as remod
15 import textwrap 15 import textwrap
16 16
17 from ..i18n import _ 17 from ..i18n import _
497 497
498 If s is not a valid boolean, returns None. 498 If s is not a valid boolean, returns None.
499 """ 499 """
500 return _booleans.get(s.lower(), None) 500 return _booleans.get(s.lower(), None)
501 501
502 def evalpython(s): 502 def evalpythonliteral(s):
503 """Evaluate a string containing a Python expression. 503 """Evaluate a string containing a Python literal expression"""
504 504 # We could backport our tokenizer hack to rewrite '' to u'' if we want
505 THIS FUNCTION IS NOT SAFE TO USE ON UNTRUSTED INPUT. IT'S USE SHOULD BE 505 return ast.literal_eval(s)
506 LIMITED TO DEVELOPER-FACING FUNCTIONALITY.
507 """
508 globs = {
509 r'__builtins__': {
510 r'None': None,
511 r'False': False,
512 r'True': True,
513 r'int': int,
514 r'set': set,
515 r'tuple': tuple,
516 # Don't need to expose dict and list because we can use
517 # literals.
518 },
519 }
520
521 # We can't use eval() directly because it inherits compiler
522 # flags from this module and we need unicode literals for Python 3
523 # compatibility.
524 code = compile(s, r'<string>', r'eval',
525 __future__.unicode_literals.compiler_flag, True)
526 return eval(code, globs, {})