diff --git a/addons/base_import_module/models/ir_module.py b/addons/base_import_module/models/ir_module.py index 05ccdc384d1..f677d880fbb 100644 --- a/addons/base_import_module/models/ir_module.py +++ b/addons/base_import_module/models/ir_module.py @@ -41,6 +41,10 @@ class view(osv.osv): for kind in ['data', 'init_xml', 'update_xml']: for filename in terp[kind]: + ext = os.path.splitext(filename)[1].lower() + if ext not in ('.xml', '.csv', '.sql'): + _logger.info("module %s: skip unsupported file %s", module, filename) + continue _logger.info("module %s: loading %s", module, filename) noupdate = False if filename.endswith('.csv') and kind in ('init', 'init_xml'): diff --git a/openerp/addons/base/res/res_users.py b/openerp/addons/base/res/res_users.py index 38625280089..841c0185932 100644 --- a/openerp/addons/base/res/res_users.py +++ b/openerp/addons/base/res/res_users.py @@ -511,6 +511,7 @@ class res_users(osv.osv): if not passwd: # empty passwords disallowed for obvious security reasons raise openerp.exceptions.AccessDenied() + db = self.pool.db_name if self.__uid_cache.setdefault(db, {}).get(uid) == passwd: return cr = self.pool.cursor() diff --git a/openerp/tools/convert.py b/openerp/tools/convert.py index f7ae2e9d89f..c332e909125 100644 --- a/openerp/tools/convert.py +++ b/openerp/tools/convert.py @@ -50,11 +50,8 @@ from yaml_import import convert_yaml_import _logger = logging.getLogger(__name__) -# Import of XML records requires the unsafe eval as well, -# almost everywhere, which is ok because it supposedly comes -# from trusted data, but at least we make it obvious now. -unsafe_eval = eval -from safe_eval import safe_eval as eval +from safe_eval import safe_eval as s_eval +safe_eval = lambda expr, ctx={}: s_eval(expr, ctx, nocopy=True) class ParseError(Exception): def __init__(self, msg, text, filename, lineno): @@ -119,7 +116,7 @@ def _eval_xml(self, node, pool, cr, uid, idref, context=None): idref2 = {} if f_search: idref2 = _get_idref(self, cr, uid, f_model, context, idref) - q = unsafe_eval(f_search, idref2) + q = safe_eval(f_search, idref2) ids = pool[f_model].search(cr, uid, q) if f_use != 'id': ids = map(lambda x: x[f_use], pool[f_model].read(cr, uid, ids, [f_use])) @@ -136,7 +133,7 @@ def _eval_xml(self, node, pool, cr, uid, idref, context=None): if a_eval: idref2 = _get_idref(self, cr, uid, f_model, context, idref) try: - return unsafe_eval(a_eval, idref2) + return safe_eval(a_eval, idref2) except Exception: logging.getLogger('openerp.tools.convert.init').error( 'Could not eval(%s) for %s in %s', a_eval, node.get('name'), context) @@ -208,7 +205,7 @@ def _eval_xml(self, node, pool, cr, uid, idref, context=None): # FIXME: should probably be exclusive if a_eval: idref['ref'] = lambda x: self.id_get(cr, x) - args = unsafe_eval(a_eval, idref) + args = safe_eval(a_eval, idref) for n in node: return_val = _eval_xml(self,n, pool, cr, uid, idref, context) if return_val is not None: @@ -241,12 +238,12 @@ class xml_import(object): for ctx in (data_node_context, node_context): if ctx: try: - ctx_res = unsafe_eval(ctx, eval_dict) + ctx_res = safe_eval(ctx, eval_dict) if isinstance(context, dict): context.update(ctx_res) else: context = ctx_res - except NameError: + except (ValueError, NameError): # Some contexts contain references that are only valid at runtime at # client-side, so in that case we keep the original context string # as it is. We also log it, just in case. @@ -285,7 +282,7 @@ form: module.record_id""" % (xml_id,) if d_search: idref = _get_idref(self, cr, self.uid, d_model, context={}, idref={}) try: - ids = self.pool[d_model].search(cr, self.uid, unsafe_eval(d_search, idref)) + ids = self.pool[d_model].search(cr, self.uid, safe_eval(d_search, idref)) except ValueError: _logger.warning('Skipping deletion for failed search `%r`', d_search, exc_info=True) pass @@ -318,14 +315,14 @@ form: module.record_id""" % (xml_id,) if rec.get(field): res[dest] = rec.get(field).encode('utf8') if rec.get('auto'): - res['auto'] = eval(rec.get('auto','False')) + res['auto'] = safe_eval(rec.get('auto','False')) if rec.get('sxw'): sxw_content = misc.file_open(rec.get('sxw')).read() res['report_sxw_content'] = sxw_content if rec.get('header'): - res['header'] = eval(rec.get('header','False')) + res['header'] = safe_eval(rec.get('header','False')) - res['multi'] = rec.get('multi') and eval(rec.get('multi','False')) + res['multi'] = rec.get('multi') and safe_eval(rec.get('multi','False')) xml_id = rec.get('id','').encode('utf8') self._test_xml_id(xml_id) @@ -349,12 +346,12 @@ form: module.record_id""" % (xml_id,) id = self.pool['ir.model.data']._update(cr, self.uid, "ir.actions.report.xml", self.module, res, xml_id, noupdate=self.isnoupdate(data_node), mode=self.mode) self.idref[xml_id] = int(id) - if not rec.get('menu') or eval(rec.get('menu','False')): + if not rec.get('menu') or safe_eval(rec.get('menu','False')): keyword = str(rec.get('keyword', 'client_print_multi')) value = 'ir.actions.report.xml,'+str(id) ir_values_id = self.pool['ir.values'].set_action(cr, self.uid, res['name'], keyword, res['model'], value) self.pool['ir.actions.report.xml'].write(cr, self.uid, id, {'ir_values_id': ir_values_id}) - elif self.mode=='update' and eval(rec.get('menu','False'))==False: + elif self.mode=='update' and safe_eval(rec.get('menu','False'))==False: # Special check for report having attribute menu=False on update value = 'ir.actions.report.xml,'+str(id) self._remove_ir_values(cr, res['name'], value, res['model']) @@ -427,8 +424,8 @@ form: module.record_id""" % (xml_id,) context = self.get_context(data_node, rec, eval_context) try: - domain = unsafe_eval(domain, eval_context) - except NameError: + domain = safe_eval(domain, eval_context) + except (ValueError, NameError): # Some domains contain references that are only valid at runtime at # client-side, so in that case we keep the original domain string # as it is. We also log it, just in case. @@ -465,7 +462,7 @@ form: module.record_id""" % (xml_id,) if rec.get('target'): res['target'] = rec.get('target','') if rec.get('multi'): - res['multi'] = eval(rec.get('multi', 'False')) + res['multi'] = safe_eval(rec.get('multi', 'False')) id = self.pool['ir.model.data']._update(cr, self.uid, 'ir.actions.act_window', self.module, res, xml_id, noupdate=self.isnoupdate(data_node), mode=self.mode) self.idref[xml_id] = int(id) @@ -592,7 +589,7 @@ form: module.record_id""" % (xml_id,) if rec_id: ids = [self.id_get(cr, rec_id)] elif rec_src: - q = unsafe_eval(rec_src, eval_dict) + q = safe_eval(rec_src, eval_dict) ids = self.pool[rec_model].search(cr, uid, q, context=context) if rec_src_count: count = int(rec_src_count) @@ -623,7 +620,7 @@ form: module.record_id""" % (xml_id,) for test in rec.findall('./test'): f_expr = test.get("expr",'').encode('utf-8') expected_value = _eval_xml(self, test, self.pool, cr, uid, self.idref, context=context) or True - expression_value = unsafe_eval(f_expr, globals_dict) + expression_value = safe_eval(f_expr, globals_dict) if expression_value != expected_value: # assertion failed self.assertion_report.record_failure() msg = 'assertion "%s" failed!\n' \ @@ -642,7 +639,7 @@ form: module.record_id""" % (xml_id,) rec_id = rec.get("id",'').encode('ascii') rec_context = rec.get("context", {}) if rec_context: - rec_context = unsafe_eval(rec_context) + rec_context = safe_eval(rec_context) if self.xml_filename and rec_id: rec_context['install_mode_data'] = dict( @@ -689,7 +686,7 @@ form: module.record_id""" % (xml_id,) f_val = False if f_search: - q = unsafe_eval(f_search, self.idref) + q = safe_eval(f_search, self.idref) assert f_model, 'Define an attribute model="..." in your .XML file !' f_obj = self.pool[f_model] # browse the objects searched