2014-03-17 22:57 GMT+01:00 Balan Victor <balan.vict...@gmail.com>: > Ho un array di tuple cosi formate da 3 elementi: > (int|float|boolean|string|datetime|..., string, boolean). Es: > > [ > (10, "value >= 1", True), > ("Ciao", "o in value", True), > (True, "value == False", False), > (92.5f, "value >= 92.0f", True), > ] > Il primo elemento della tupla può essere qualunque tipo o classe di python. > Il secondo elemento è una espressione da applicare sulla tupla e che deve > restituire True or False(value si riferisce al primo elemento della tupa) > Il terzo elemento è il risultato dell'operazione appena sopra. > > A intervalli regolari ho bisogno di scorrere l'array sopra e aggiornare il > valore del terzo elemento. > Ho pensato di usare eval in questo modo: > > def check_status(value, eval_string): > rc = eval(eval_string) > if rc is not bool: raise WrongEvalString() > return rc > > Conosco i rischi di eval e vorrei evitare di usarlo però non riesco a > trovare nulla di altrettanto semplice e con le stesse potenzialità. > > eval è relativamente sicuro, dato che può eseguire solo espressioni, e non statement completi come exec. Lo puoi rendere ancora più sicuro limitando il namespace, ad esempio:
def expand_template(template, **kwargs): from string import Template return Template(template).substitute(**kwargs) def eval_expression(expr_literal, value): expr = expand_template(expr_literal, value=value) return eval(expr, {}, {}) def check_status(value, eval_string): rc = eval_expression(eval_string, value) if rc is not True: raise WrongEvalString() check_status(10, "$value == 10") Questo però non basta, devi avere il controllo anche su value, ad esempio accettando solo stringhe secondo un dato protocollo, di cui farai il parsing e validazione. Il mio protocollo preferito è "Typed NetStrings": "<typeid><len>:<literal> Ad esempio per un intero: "i3:777" tale protocollo è facile da leggere, parsare e validare (perchè verboso) NB: In realtà la stringa che fa la validazione può essere impostata solo da > qualcuno di autorizzato quindi il rischio che mi cancelli tutto il fs non > ci dovrebbe essere, e non dovrebbero nemmeno fare operazioni del tipo > "value ** value" però in ogni caso vorrei trovare qualcosa che mi metta al > sicuro da questo tipo di operazioni. > Riguardo operazioni non autorizzate sei abbastanza al sicuro, grazie al fatto che eval esegue solo espressioni, ed al fatto che valuti solo oggetti a te noti. In caso di dubbi, leggi la grammatica di Python per sapere cosa può contenere una espressione. Riguardo "value ** value" temi un attacco di tipo DoS? In questo caso se vuoi limitare anche le possibili espressioni, l'unica alternativa e scriverti un tuo parser, come ti hanno già suggerito. Dai una occhiata al modulo ast di Python. Ciao Manlio
_______________________________________________ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python