From bb79ae54b2b1448cc0e448c4f068539583255a7d Mon Sep 17 00:00:00 2001 From: Aki Tuomi Date: Sun, 7 Jun 2026 11:46:58 +0000 Subject: [PATCH 1/3] upgrade: Note that safe filter must be last in pipeline --- docs/installation/upgrade/2.4-to-2.4.x.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/installation/upgrade/2.4-to-2.4.x.md b/docs/installation/upgrade/2.4-to-2.4.x.md index c411f4267..e5e485e16 100644 --- a/docs/installation/upgrade/2.4-to-2.4.x.md +++ b/docs/installation/upgrade/2.4-to-2.4.x.md @@ -17,7 +17,7 @@ dovecotlinks: ### v2.4.2 to v2.4.3 - * Using [[link,settings_variables]] with LDAP settings now requires using `| safe` filter to allow passing through LDAP characters that are otherwise escaped. Note that this should be used only for variables coming from trusted sources, not for e.g. username variable. + * Using [[link,settings_variables]] with LDAP settings now requires using `| safe` filter to allow passing through LDAP characters that are otherwise escaped. The `safe` filter must always be the last filter in the pipeline. Note that this should be used only for variables coming from trusted sources, not for e.g. username variable. #### Changed Setting Defaults From 8403386445ff2d624d075466d3dcb048681933a4 Mon Sep 17 00:00:00 2001 From: Aki Tuomi Date: Sun, 7 Jun 2026 15:08:01 +0300 Subject: [PATCH 2/3] variables: Indicate safe must be last in pipeline --- docs/core/settings/variables.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/core/settings/variables.md b/docs/core/settings/variables.md index 9cd8f7c49..2cf97cca8 100644 --- a/docs/core/settings/variables.md +++ b/docs/core/settings/variables.md @@ -53,6 +53,8 @@ a provider. There are global providers, and context-specific providers. A variable can be then filtered with various filters, such as `%{variable | upper}` to get uppercase representation of variable. You can chain as many filters as you need. +If a pipeline contains the `safe` filter, it applies to the whole pipeline output. +The `safe` filter must always be the last filter in the pipeline. Filters can accept parameters, both positional and named. E.g. `%{literal('\r\n\')}` will expand to CR LF. `%{user | substr(0, 1)}` will take first character of username. Example of named parameters @@ -139,7 +141,7 @@ Bytes output type indicates that the output will be tagged as binary output. Sub | `unhexlify` | String | Bytes | Convert hex encoded input into bytes. | | `upper` | String | String | Uppercases input. | | `username` | String | String | Provides user part of user@domain value. | -| `safe` | String | String | Don't escape the variable output. This is mainly intended for [[setting,ldap_base]] when the DN comes from a variable. [[added,variables_safe_added]] | +| `safe` | String | String | Don't escape the output of the whole pipeline. This must always be the last filter in the pipeline. This is mainly intended for [[setting,ldap_base]] when the DN comes from a variable. [[added,variables_safe_added]] | ## Global providers From f5b2fcc2a06ecd486084db047dbe5eec511c1adf Mon Sep 17 00:00:00 2001 From: Aki Tuomi Date: Sun, 7 Jun 2026 11:47:08 +0000 Subject: [PATCH 3/3] variables: document escape filter --- data/updates.js | 1 + docs/core/settings/variables.md | 1 + docs/installation/upgrade/2.4-to-2.4.x.md | 6 ++++++ 3 files changed, 8 insertions(+) diff --git a/data/updates.js b/data/updates.js index a473becc2..3345d698a 100644 --- a/data/updates.js +++ b/data/updates.js @@ -88,6 +88,7 @@ export const updates = { variables_owner_user_added: '2.4.0', var_expand: '2.4.0', variables_oauth2: '2.4.3', + variables_escape_added: '2.4.5', variables_safe_added: '2.4.3', variables_switch_added: '2.4.3', xclient_dest_added: '2.4.3', diff --git a/docs/core/settings/variables.md b/docs/core/settings/variables.md index 2cf97cca8..e62e9eef4 100644 --- a/docs/core/settings/variables.md +++ b/docs/core/settings/variables.md @@ -110,6 +110,7 @@ Bytes output type indicates that the output will be tagged as binary output. Sub | `domain` | String | String | Provides domain part of user@domain value. | | `encrypt(key=bytes, iv=bytes, raw=boolean, algorithm=string)` | Any | Any | Encrypts given input, see [cryptography support](#cryptography-support). | | `encrypt(key=string, salt=string, rounds=number, raw=boolean, hash=string, algorithm=string)` | Any | Any | Encrypts given input, see [cryptography support](#cryptography-support). | +| `escape` | String | String | Apply the configured escape function to the input. Returns an error if no escape function is configured. This filter is intended to be used with `safe` filter, when used without, the output is escaped again at output time (double-escaped). [[added,variables_escape_added]] | | `hash(method, rounds=number, salt=string)` | Bytes | Bytes | Returns raw hash from input using given hash method. Rounds and salt are optional. | | `hexlify(width)` | Bytes | String | Convert bytes into hex with optional width, truncates or pads up to width. | | `hex(width)` | Number | Number | Convert base-10 number to base-16 number. If width is specified the result is truncated or padded with 0 to width. Negative width is applied after number. | diff --git a/docs/installation/upgrade/2.4-to-2.4.x.md b/docs/installation/upgrade/2.4-to-2.4.x.md index e5e485e16..54f12575c 100644 --- a/docs/installation/upgrade/2.4-to-2.4.x.md +++ b/docs/installation/upgrade/2.4-to-2.4.x.md @@ -118,6 +118,12 @@ changed to `2.4.4`. ### v2.4.4 to v2.4.5 +#### New Features + +| Feature | Notes | +| ------- | ----- | +| [[link,settings_variables,`escape` filter]] | Explicitly apply the configured escape function within a variable expansion pipeline. Useful for partial escaping when combined with `concat` and `safe`. | + #### Removed Features | Feature | Notes |