Skip to content

translation-format-interpolation (ODW8302)

Preview (since 0.16.2.9) · Related issues · View source

Derived from the odoo linter.

Fix is sometimes available.

This rule is unstable and in preview. The --preview flag is required for use.

What it does

Checks for translation calls interpolated with str.format, either on the term (_("Hello {}".format(name))) or on the translated result (_("Hello {}").format(name)).

The rule only applies from Odoo 14.0 on, the version whose translation functions take the interpolation arguments themselves; up to 13.0 translation-contains-variable covers the eager interpolation instead. Configure the version with the odoo-version setting; without it the rule stays enabled.

Why is this bad?

Since Odoo 14.0 the translation functions (_, self.env._) interpolate the values themselves using printf-style placeholders: _("Hello %s", name). Formatting the term interpolates before translation, so the looked-up term never matches the exported translation entry; formatting the result lets a malicious translation access attributes of the format arguments.

Example

_("Hello {}").format(name)

Use instead:

_("Hello %s", name)

Fix safety

A fix is offered when the template only uses bare {} fields, the format call passes exactly that many positional arguments, and the literal spells no character through an escape sequence: the fields become %s, literal braces and % are re-escaped, and the arguments move into the translation call. The fix is marked unsafe because the term the translation machinery looks up changes (Hello {} becomes Hello %s), so the exported translation entries have to be regenerated.