From bac77cf1c782dd349dbfb0bea7badcd417dca68e Mon Sep 17 00:00:00 2001 From: John Coffey Date: Mon, 26 Oct 2026 23:08:53 -0700 Subject: [PATCH] Sieve: accept the pre-rename vnd.stalwart.* extension names A script written for upstream that requires vnd.stalwart.expressions or vnd.stalwart.while keeps running after a move to INBUXA, since scripts are stored compiled. But it can't be saved again once edited: the old name parses as an unknown extension, and let or eval then fails with "Undeclared capability 'vnd.inbuxa.expressions'". Both spellings now parse to the same capability. Only the INBUXA names are advertised. --- tools/fork/name-allowlist.txt | 6 +++++ vendor/sieve-rs/VENDORED.md | 6 ++++- vendor/sieve-rs/src/compiler/grammar/mod.rs | 30 +++++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/tools/fork/name-allowlist.txt b/tools/fork/name-allowlist.txt index 6f108a43..ccabf55f 100644 --- a/tools/fork/name-allowlist.txt +++ b/tools/fork/name-allowlist.txt @@ -23,6 +23,12 @@ crates/migration/src/lib.rs "STALWART_SPAM_CLASSIFIER_MODEL.lz4" crates/migration/src/lib.rs "STALWART_SPAM_TRAIN_DATA.lz4" crates/types/src/branding.rs "STALWART" +# Pre-rename Sieve extension names, accepted as aliases so scripts written +# for upstream still compile when edited. Never advertised; the test proves it. +vendor/sieve-rs/src/compiler/grammar/mod.rs "vnd.stalwart.while" +vendor/sieve-rs/src/compiler/grammar/mod.rs "vnd.stalwart.expressions" +vendor/sieve-rs/src/compiler/grammar/mod.rs "require [\\\"vnd.stalwart.expressions\\\", \\\"variables\\\"];\\nlet \\\"n\\\" \\\"1 + 2\\\";\\n" + # Upstream's old default rules source, read only to treat it as unset: the # server uses the rules bundled with it (resources/spam-filter/). crates/common/src/manager/spam_rules.rs "https://github.com/stalwartlabs/spam-filter/releases/latest/download/spam-filter-rules.json.gz" diff --git a/vendor/sieve-rs/VENDORED.md b/vendor/sieve-rs/VENDORED.md index 2cdf7a6d..d5e40258 100644 --- a/vendor/sieve-rs/VENDORED.md +++ b/vendor/sieve-rs/VENDORED.md @@ -11,7 +11,11 @@ Every changed file carries the AGPL 5(a) notice in its header. - `src/compiler/grammar/mod.rs`: the extensions scripts `require` and ManageSieve advertises are `vnd.inbuxa.while` and - `vnd.inbuxa.expressions`. + `vnd.inbuxa.expressions`. The pre-rename `vnd.stalwart.*` spellings are + still accepted, never advertised, so a script written for upstream compiles + when it's edited. Without them, the name is treated as an unknown extension + and `let` or `eval` fails with "Undeclared capability". The + `legacy_extension_names` tests cover both. - `src/runtime/mod.rs`: the default `environment "name"` is `inbuxa Sieve` (the server sets its own name on both of its runtimes anyway), and the test-only capability is `vnd.inbuxa.testsuite`. diff --git a/vendor/sieve-rs/src/compiler/grammar/mod.rs b/vendor/sieve-rs/src/compiler/grammar/mod.rs index 59a9f90b..f9f4c187 100644 --- a/vendor/sieve-rs/src/compiler/grammar/mod.rs +++ b/vendor/sieve-rs/src/compiler/grammar/mod.rs @@ -732,5 +732,35 @@ fn lookup_capabilities(input: &str) -> Option { // Extensions "vnd.inbuxa.while" => Capability::While, "vnd.inbuxa.expressions" => Capability::Expressions, + // The pre-rename spellings, so scripts written for upstream still + // compile when they're edited. They're never advertised. + "vnd.stalwart.while" => Capability::While, + "vnd.stalwart.expressions" => Capability::Expressions, ) } + +#[cfg(test)] +mod legacy_extension_names { + use super::Capability; + use crate::Compiler; + + #[test] + fn old_spelling_parses_new_spelling_is_shown() { + for (old, new) in [ + ("vnd.stalwart.while", "vnd.inbuxa.while"), + ("vnd.stalwart.expressions", "vnd.inbuxa.expressions"), + ] { + let parsed = Capability::parse(old); + assert_eq!(parsed.to_string(), new); + assert_eq!(parsed, Capability::parse(new)); + } + } + + #[test] + fn script_using_old_spelling_compiles() { + let script = b"require [\"vnd.stalwart.expressions\", \"variables\"];\nlet \"n\" \"1 + 2\";\n"; + Compiler::new() + .compile(script) + .expect("a script requiring the pre-rename name compiles"); + } +} -- 2.54.0