[FIX] base: check ir.ui.view recursion

This commit is contained in:
Christophe Simonis 2017-03-09 15:42:00 +01:00
parent 70cac4d474
commit 7a15e52cea
2 changed files with 26 additions and 0 deletions

View File

@ -111,6 +111,7 @@ xpath_utils['hasclass'] = _hasclass
class view(osv.osv):
_name = 'ir.ui.view'
_parent_name = 'inherit_id' # used for recursion check
def _get_model_data(self, cr, uid, ids, fname, args, context=None):
result = dict.fromkeys(ids, False)
@ -188,6 +189,10 @@ class view(osv.osv):
return self._relaxng_validator
def _check_xml(self, cr, uid, ids, context=None):
# As all constraints are verified on create/write, we must re-check that there is no
# recursion before calling `read_combined` to avoid an infinite loop.
if not self._check_recursion(cr, uid, ids, context=context):
return True # pretend arch is valid to avoid misleading user about the error.
if context is None:
context = {}
context = dict(context, check_view_ids=ids)
@ -225,6 +230,7 @@ class view(osv.osv):
]
_constraints = [
(_check_xml, 'Invalid view definition', ['arch']),
(osv.osv._check_recursion, 'You cannot create recursive inherited views.', ['inherit_id']),
]
def _auto_init(self, cr, context=None):

View File

@ -9,6 +9,7 @@ from lxml.builder import E
from psycopg2 import IntegrityError
from openerp.exceptions import ValidationError
from openerp.tests import common
import openerp.tools
@ -243,6 +244,25 @@ class TestViewInheritance(ViewCase):
self.View.default_view(
self.cr, self.uid, model=self.model, view_type='graph'))
def test_no_recursion(self):
r1 = self.makeView('R1')
with self.assertRaises(ValidationError), self.cr.savepoint():
self.View.write(self.cr, self.uid, r1, {'inherit_id': r1})
r2 = self.makeView('R2', r1)
r3 = self.makeView('R3', r2)
with self.assertRaises(ValidationError), self.cr.savepoint():
self.View.write(self.cr, self.uid, r2, {'inherit_id': r3})
with self.assertRaises(ValidationError), self.cr.savepoint():
self.View.write(self.cr, self.uid, r1, {'inherit_id': r3})
with self.assertRaises(ValidationError), self.cr.savepoint():
self.View.write(self.cr, self.uid, r1, {
'inherit_id': r1,
'arch': self.arch_for('itself', parent=True),
})
class TestApplyInheritanceSpecs(ViewCase):
""" Applies a sequence of inheritance specification nodes to a base
architecture. IO state parameters (cr, uid, model, context) are used for