[FIX] base: avoid infinite recursion on attachments search
Steps to reproduce:
Create a new local Odoo DB
Create another company on the DB
install the CRM module
Create an opportunity on the CRM app for each company.
Execute This server action (CHANGE THE res_id TO THE IDs OF THE OPPORTUNITY CREATED):
```
for _ in range(0, 300):
for _ in range (0, 75):
env['ir.attachment'].sudo().create({'name': 'test','res_model': 'crm.lead', 'res_id': 31, 'type': 'binary'})
for _ in range (0, 75):
env['ir.attachment'].sudo().create({'name': 'test','res_model': 'crm.lead', 'res_id': 45, 'type': 'binary'})
```
go to the Settings / Technical / Database Structure / Attachments.
Server will look in endless call because the search try to retrieve
`limit` records, but after applying company record rule we have
`limit - e`, so it begin a second search for e records.
Even the second search will look for limit and possibly will find less,
starting a third...
If the sub call is aware of how much records we actually need after
checking permission, we can return the recordset if we have collected
enough
opw-2369722
closes odoo/odoo#62456
X-original-commit: 6a8f28c4d0f9df7cd8451f4caf4f3bf7d64330da
Signed-off-by: agr-odoo <agr-odoo@users.noreply.github.com>
This commit is contained in:
@@ -489,11 +489,14 @@ class IrAttachment(models.Model):
|
||||
result = [id for id in orig_ids if id in ids]
|
||||
|
||||
# If the original search reached the limit, it is important the
|
||||
# filtered record set does so too. When a JS view recieve a
|
||||
# record set whose length is bellow the limit, it thinks it
|
||||
# reached the last page.
|
||||
if len(orig_ids) == limit and len(result) < len(orig_ids):
|
||||
result.extend(self._search(args, offset=offset + len(orig_ids),
|
||||
# filtered record set does so too. When a JS view receive a
|
||||
# record set whose length is below the limit, it thinks it
|
||||
# reached the last page. To avoid an infinite recursion due to the
|
||||
# permission checks the sub-call need to be aware of the number of
|
||||
# expected records to retrieve
|
||||
if len(orig_ids) == limit and len(result) < self._context.get('need', limit):
|
||||
need = self._context.get('need', limit) - len(result)
|
||||
result.extend(self.with_context(need=need)._search(args, offset=offset + len(orig_ids),
|
||||
limit=limit, order=order, count=count,
|
||||
access_rights_uid=access_rights_uid)[:limit - len(result)])
|
||||
|
||||
|
||||
Reference in New Issue
Block a user