[IMP] safe_eval: do not log exceptions, when re-raising a new exception, make the...
[odoo/odoo.git] / openerp / tools / safe_eval.py
index a542fa4..c56c94e 100644 (file)
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 ##############################################################################
-#    Copyright (C) 2004-2010 OpenERP s.a. (<http://www.openerp.com>).
+#    Copyright (C) 2004-2012 OpenERP s.a. (<http://www.openerp.com>).
 #
 #    This program is free software: you can redistribute it and/or modify
 #    it under the terms of the GNU Affero General Public License as
@@ -34,7 +34,6 @@ condition/math builtins.
 from opcode import HAVE_ARGUMENT, opmap, opname
 from types import CodeType
 import logging
-import os
 
 __all__ = ['test_expr', 'safe_eval', 'const_eval']
 
@@ -46,7 +45,7 @@ _ALLOWED_MODULES = ['_strptime', 'time']
 _CONST_OPCODES = set(opmap[x] for x in [
     'POP_TOP', 'ROT_TWO', 'ROT_THREE', 'ROT_FOUR', 'DUP_TOP', 'DUP_TOPX',
     'POP_BLOCK','SETUP_LOOP', 'BUILD_LIST', 'BUILD_MAP', 'BUILD_TUPLE',
-    'LOAD_CONST', 'RETURN_VALUE', 'STORE_SUBSCR'] if x in opmap)
+    'LOAD_CONST', 'RETURN_VALUE', 'STORE_SUBSCR', 'STORE_MAP'] if x in opmap)
 
 _EXPR_OPCODES = _CONST_OPCODES.union(set(opmap[x] for x in [
     'UNARY_POSITIVE', 'UNARY_NEGATIVE', 'UNARY_NOT',
@@ -61,7 +60,7 @@ _EXPR_OPCODES = _CONST_OPCODES.union(set(opmap[x] for x in [
     ] if x in opmap))
 
 _SAFE_OPCODES = _EXPR_OPCODES.union(set(opmap[x] for x in [
-    'STORE_MAP', 'LOAD_NAME', 'CALL_FUNCTION', 'COMPARE_OP', 'LOAD_ATTR',
+    'LOAD_NAME', 'CALL_FUNCTION', 'COMPARE_OP', 'LOAD_ATTR',
     'STORE_NAME', 'GET_ITER', 'FOR_ITER', 'LIST_APPEND', 'DELETE_NAME',
     'JUMP_FORWARD', 'JUMP_IF_TRUE', 'JUMP_IF_FALSE', 'JUMP_ABSOLUTE',
     'MAKE_FUNCTION', 'SLICE+0', 'SLICE+1', 'SLICE+2', 'SLICE+3',
@@ -107,11 +106,11 @@ def test_expr(expr, allowed_codes, mode="eval"):
             expr = expr.strip()
         code_obj = compile(expr, "", mode)
     except (SyntaxError, TypeError):
-        _logger.debug('Invalid eval expression', exc_info=True)
         raise
-    except Exception:
-        _logger.debug('Disallowed or invalid eval expression', exc_info=True)
-        raise ValueError("%s is not a valid expression" % expr)
+    except Exception, e:
+        import sys
+        exc_info = sys.exc_info()
+        raise ValueError, '"%s" while compiling\n%s' % (str(e), expr), exc_info[2]
     for code in _get_opcodes(code_obj):
         if code not in allowed_codes:
             raise ValueError("opcode %s not allowed (%r)" % (opname[code], expr))
@@ -238,6 +237,7 @@ def safe_eval(expr, globals_dict=None, locals_dict=None, mode="eval", nocopy=Fal
                 'set' : set
             }
     )
-    return eval(test_expr(expr,_SAFE_OPCODES, mode=mode), globals_dict, locals_dict)
+    c = test_expr(expr, _SAFE_OPCODES, mode=mode)
+    return eval(c, globals_dict, locals_dict)
 
 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: