Skip to content

[18.0][FIX] auditlog: prevent recursion on re-entrant write from compute/inverse#3658

Open
midhlaj-nk wants to merge 1 commit into
OCA:18.0from
midhlaj-nk:18.0-fix-auditlog-recursion-on-write
Open

[18.0][FIX] auditlog: prevent recursion on re-entrant write from compute/inverse#3658
midhlaj-nk wants to merge 1 commit into
OCA:18.0from
midhlaj-nk:18.0-fix-auditlog-recursion-on-write

Conversation

@midhlaj-nk

Copy link
Copy Markdown

Problem

When an auditlog rule is active for a model that has compute or inverse methods that trigger write() on the same model (e.g. account.account with _compute_code / _inverse_code), a RecursionError: maximum recursion depth exceeded is raised.

Root cause: write_full and write_fast set auditlog_disabled=True via self = self.with_context(auditlog_disabled=True), which only modifies the local self. Compute/inverse methods triggered by the original write call write() on the model class using their own self, which does not carry the modified context. This causes the patched write_full/write_fast to re-enter indefinitely.

Closes #3512

Solution

Add an early-exit guard as the first statement of both write_full and write_fast:

if self.env.context.get("auditlog_disabled"):
    return write_full.origin(self, vals, **kwargs)

When a re-entrant write call arrives (already carrying auditlog_disabled=True), the closure immediately delegates to the origin and returns — no logging, no further recursion.

Tests

Added TestAuditlogRecursion with three test cases:

  • test_no_recursion_write_full_reentrant: company write syncs address to child partner (both audited, full log) — verifies no RecursionError
  • test_no_recursion_write_fast_reentrant: same scenario with fast log
  • test_write_full_guard_skips_logging: write with auditlog_disabled=True in context produces no log entry — verifies guard path is taken

…ute/inverse

write_full and write_fast set auditlog_disabled on a rebound local self via
with_context(), but compute/inverse methods triggered by the original write
(e.g. AccountAccount._compute_code / _inverse_code) call write() on the model
class using their own self, which does not carry the modified context. This
causes write_full/write_fast to re-enter indefinitely, hitting Python's
recursion limit.

Add an early-exit guard at the top of both closures: if auditlog_disabled is
already in context, delegate immediately to the origin write and return.

Closes OCA#3512
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Auditlog: Maximum recursion error when creating new accounts

2 participants