Sieve: match any key, and :regex dates as regular expressions #236

Merged
jcoffey-dev merged 1 commits from fix/sieve-match-bugs into main 2026-10-29 18:54:03 +00:00
Owner

Two Sieve matching bugs, both inherited from upstream sieve-rs 0.7.3.

  • string depended on key order. It compared each key against every source, but its break on a match only left the loop over sources, so the next key overwrote the result. string :is "a" ["a", "b"] was false while ["b", "a"] was true. RFC 5229 makes a test true when any key matches. It now stops at the first match.
  • date :regex and currentdate :regex weren't regular expressions. They called the :matches comparator, so "^20[0-9]{2}$" was read as a wildcard pattern and never matched a year. They now use the regex comparator, with the same size limit and cache as every other test.

A user's filter that hit either bug silently misfiled mail.

Tested:

  • sieve_tests_match_any_key_and_regex_dates in crates/common: passes, and fails without the fix.
  • sieve-rs's own tests with upstream's svtests restored in full: 10 passed.
  • clippy on the vendored crate is clean, and cargo fmt --all --check is clean.

Found by batch 3 group M (OPPORTUNITIES); the date one turned up while checking the other tests for the same loop.

Two Sieve matching bugs, both inherited from upstream sieve-rs 0.7.3. - **`string` depended on key order.** It compared each key against every source, but its `break` on a match only left the loop over sources, so the next key overwrote the result. `string :is "a" ["a", "b"]` was false while `["b", "a"]` was true. RFC 5229 makes a test true when any key matches. It now stops at the first match. - **`date :regex` and `currentdate :regex` weren't regular expressions.** They called the `:matches` comparator, so `"^20[0-9]{2}$"` was read as a wildcard pattern and never matched a year. They now use the regex comparator, with the same size limit and cache as every other test. A user's filter that hit either bug silently misfiled mail. Tested: - `sieve_tests_match_any_key_and_regex_dates` in crates/common: passes, and fails without the fix. - sieve-rs's own tests with upstream's svtests restored in full: 10 passed. - clippy on the vendored crate is clean, and `cargo fmt --all --check` is clean. Found by batch 3 group M (OPPORTUNITIES); the date one turned up while checking the other tests for the same loop.
jcoffey-dev added 1 commit 2026-10-29 18:41:52 +00:00
Sieve: match any key, and :regex dates as regular expressions
ci / fork-checks (pull_request) Skipped
ci / build (pull_request) Skipped
github/ci (branch) GitHub Actions
ci / github (pull_request) Successful in 10m7s
dacc7167cd
string compared each key against every source, but its break on a match
only left the loop over sources, so the next key overwrote the result:
string :is "a" ["a", "b"] was false while ["b", "a"] was true. RFC 5229
makes a test true when any key matches. It now stops at the first match.

date :regex and currentdate :regex called the :matches comparator, so a
regular expression was read as a wildcard pattern and "^20[0-9]{2}$"
never matched a year. They now use the regex comparator, with its size
limit and cache, like every other test.

sieve_tests_match_any_key_and_regex_dates in crates/common covers both
and fails without the fix. Upstream's svtests (restored in full) pass.
jcoffey-dev merged commit 9bdcdb4f6f into main 2026-10-29 18:54:03 +00:00
jcoffey-dev deleted branch fix/sieve-match-bugs 2026-10-29 18:54:04 +00:00
Sign in to join this conversation.