On Apr 11, 3:18 am, Joel Hedlund <yoh...@ifm.liu.se> wrote: > Aaron Brady wrote: > > Would you be willing to examine a syntax tree to determine if there > > are any class accesses? > > Sure? How do I do that? I've never done that type of thing before so I > can't really say if it would work or not. > > /Joel
NO PROMISES. No warranty is made, express or implied. Of course, something this devious, a "white" list, may just make it so your enemy finds out its weakness before you do. It's ostensibly for Python 3, but IIRC there's a way to do it in 2. 'ast.literal_eval' appears to evaluate a literal, but won't do expressions, which is what you are looking for. We should refer people to it more often. +1 ast.walk, btw. If you want subtraction and division, you'll have to add them yourself. You could probably compress the 'is_it_safe' function to one line, provided that it's sound to start with: if all( x in safe_node_classes for x in ast.walk( ast.parse( exp ) ) ), or better yet, if set( ast.walk( ast.parse( exp ) ) )<= safe_node_classes. +1! /Source: import ast safe_exp= '( 2+ 4 )* 7' unsafe_exp= '( 2+ 4 ).__class__' unsafe_exp2= '__import__( "os" )' safe_node_classes= set( [ ast.Module, ast.Expr, ast.BinOp, ast.Mult, ast.Add, ast.Num ] ) def is_it_safe( exp ): print( 'trying %s'% exp ) top= ast.parse( exp ) for node in ast.walk( top ): print( node ) if node.__class__ not in safe_node_classes: return False print( 'ok!' ) return True print( safe_exp, is_it_safe( safe_exp ) ) print( ) print( unsafe_exp, is_it_safe( unsafe_exp ) ) print( ) print( unsafe_exp2, is_it_safe( unsafe_exp2 ) ) print( ) /Output: trying ( 2+ 4 )* 7 <_ast.Module object at 0x00BB5DF0> <_ast.Expr object at 0x00BB5E10> <_ast.BinOp object at 0x00BB5E30> <_ast.BinOp object at 0x00BB5E50> <_ast.Mult object at 0x00BAF590> <_ast.Num object at 0x00BB5EB0> <_ast.Num object at 0x00BB5E70> <_ast.Add object at 0x00BAF410> <_ast.Num object at 0x00BB5E90> ok! ( 2+ 4 )* 7 True trying ( 2+ 4 ).__class__ <_ast.Module object at 0x00BB5E90> <_ast.Expr object at 0x00BB5DF0> <_ast.Attribute object at 0x00BB5E10> ( 2+ 4 ).__class__ False trying __import__( "os" ) <_ast.Module object at 0x00BB5E10> <_ast.Expr object at 0x00BB5E30> <_ast.Call object at 0x00BB5E50> __import__( "os" ) False -- http://mail.python.org/mailman/listinfo/python-list