Skip to content

Commit

Permalink
[FIX] core: fix recursion check
Browse files Browse the repository at this point in the history
Prevent an infinite loop when the cycle in the parents does not contain
the starting id: `3->2->1->2->1...`

Example:
```
>>> m=self.env['ir.module.category']
>>> c1,c2,c3 = map(m.browse,[1,2,3])
>>> c2.parent_id = False
>>> c3.parent_id = False
>>> c1.parent_id = c2
>>> (c3|c2).parent_id = c1  # this never ends
```

With current patch the call to `_check_recursion` successfully detects
the new cycle.

closes #151538

X-original-commit: d07ffce
Signed-off-by: Raphael Collet <rco@odoo.com>
Signed-off-by: Alvaro Fuentes Suarez (afu) <afu@odoo.com>
  • Loading branch information
aj-fuentes committed Jan 29, 2024
1 parent 1cd8788 commit ba1ba88
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 1 deletion.
8 changes: 8 additions & 0 deletions odoo/addons/base/tests/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,14 @@ def test_110_res_partner_recursion_multi_update(self):
ps = self.p1 + self.p2 + self.p3
self.assertTrue(ps.write({'phone': '123456'}))

def test_111_res_partner_recursion_infinite_loop(self):
""" The recursion check must not loop forever """
self.p2.parent_id = False
self.p3.parent_id = False
self.p1.parent_id = self.p2
with self.assertRaises(ValidationError):
(self.p3|self.p2).write({'parent_id': self.p1.id})


class TestParentStore(TransactionCase):
""" Verify that parent_store computation is done right """
Expand Down
4 changes: 3 additions & 1 deletion odoo/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4389,12 +4389,14 @@ def _check_recursion(self, parent=None):
query = 'SELECT "%s" FROM "%s" WHERE id = %%s' % (parent, self._table)
for id in self.ids:
current_id = id
seen_ids = {current_id}
while current_id:
cr.execute(query, (current_id,))
result = cr.fetchone()
current_id = result[0] if result else None
if current_id == id:
if current_id in seen_ids:
return False
seen_ids.add(current_id)
return True

@api.multi
Expand Down

0 comments on commit ba1ba88

Please sign in to comment.