Sieve Email Filtering: Variables Extension
updated by
- rfc-5173 — Sieve Email Filtering: Body Extension
updates
- rfc-5228 — Sieve: An Email Filtering Language
Extracted elements (25)
Namespaces are reserved for future extensions that make internal state available through variables. Extensions using namespaces SHOULD use their capability string as the first namespace component and SHOULD state which namespace variables are modifiable via "set".
No looping construct is provided intentionally, ensuring that all Sieve scripts terminate in an orderly manner. This keeps the language suitable for simple filtering without risk of infinite loops in a mail delivery path.
The "relational" extension [RFC 5231] adds a ":count" match type to the "string" test. For counting purposes, the count of a single string is 0 if it is empty or 1 otherwise; the count of a string list is the sum of the counts of its members.
An implementation MUST support at least 128 distinct variables, variable names of at least 32 characters, and each variable MUST be able to hold at least 4000 characters.
Attempts to set a variable to a value exceeding implementation limits SHOULD be reported as a compile-time error if possible; if discovered at run-time, the value SHOULD be truncated and MUST NOT be treated as an error.
In the "string" test, whitespace stripping MUST NOT be done unless the script explicitly requests it through some future mechanism.
Match variables ${1} through ${9} MUST be supported. References to higher indices than those the implementation supports MUST be treated as a syntax error, which SHOULD be discovered at compile-time.
References to namespaces without a prior require statement for the relevant extension MUST cause an error.
The expanded string MUST use the variable values that are current when control reaches the statement the string is part of.
The interpreter MUST short-circuit tests (not perform more tests than necessary) and MUST evaluate in left-to-right order. If a test has two or more list arguments, iteration order over them is implementation-defined.
The name argument of "set" MUST be a constant string conforming to variable-name syntax. An invalid name MUST be detected as a syntax error. Match variables cannot be set.
Unknown modifiers MUST yield a syntax error. Using two or more modifiers of the same precedence in a single "set" action is an error.
Variable names are case insensitive, so "foo" and "FOO" refer to the same variable. Unknown variables MUST be replaced by the empty string.
When a string is evaluated, substrings matching variable-ref SHALL be replaced by the value of variable-name. Only one pass through the string SHALL be done.
A variable reference is written as "${" followed by an optional namespace (identifier "." components) and a variable-name, closed by "}". Variable names are either numeric (match variables) or identifiers; unknown variables expand to the empty string.
Backslash quoting is resolved before variable substitution; encoded character processing (per RFC 5228 Section 2.4.2.4) is performed before variable substitution but after quoting. This ordering ensures that "${fo\o}" yields the expansion of variable "foo".
Match variables have names consisting only of decimal digits (e.g., ${1}, ${2}). They index the list of captured substrings from the most recently evaluated successful ":matches" test, with ${0} holding the full matched portion and ${1}..${N} holding per-wildcard captures. Non-greedy matching is used.
The ":quotewildcard" modifier escapes "*", "?", and "\" with a preceding "\" so the resulting string matches only literal occurrences when used as a ":matches" pattern.
The "set" action stores a value in a named variable: "set [MODIFIER] <name: string> <value: string>". The name must be a constant string conforming to variable-name syntax; match variables and namespaces (unless explicitly allowed) cannot be targets.
The "set" action supports modifiers applied before storing: ":lower" (precedence 40), ":upper" (40), ":lowerfirst" (30), ":upperfirst" (30), ":quotewildcard" (20), ":length" (10). Higher-precedence modifiers are applied first; using two modifiers of equal precedence is an error.
The "string" test ("string [MATCH-TYPE] [COMPARATOR] <source: string-list> <key-list: string-list>") evaluates to true if any source string matches any key. The default match type is ":is"; both source and key-list come from the script, not the message.
This document registers the Sieve capability named "variables" with IANA, adding variable support to the Sieve email filtering language.
Sieve filtering should not be relied on as a security measure against hostile mail; it is designed for simple, mostly static tests and is unsuitable as a spam or virus checker where adversaries actively vary mail format to evade rules.
Values stored by "set" that exceed implementation limits are silently truncated at run-time, making variables inappropriate for storing large structures with security implications. The absence of a looping construct ensures all Sieve scripts terminate in an orderly manner.
When match variables are used, strings may contain arbitrary values controlled by the sender of the mail, enabling potential injection of unexpected content into Sieve actions or tests.