From a47412aef9faec369bf62ef2bb4eb120b0a5d442 Mon Sep 17 00:00:00 2001 From: Skaywalker <115165402+Skaywalker@users.noreply.github.com> Date: Mon, 26 Oct 2026 09:46:25 +0100 Subject: [PATCH] proof: an AF count below 1 rejects the table, flags stay literal (#735) --- crates/proof/src/affix.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/proof/src/affix.rs b/crates/proof/src/affix.rs index 3fbb756f6..7d4fc1821 100644 --- a/crates/proof/src/affix.rs +++ b/crates/proof/src/affix.rs @@ -447,7 +447,8 @@ fn parse_aff(aff: &str) -> Result { "AF" => { if !af_header { af_header = true; - r.aliases_on = at(1).parse::().is_ok(); + // A count below 1 rejects the table too: flags stay literal (`AF 0`). + r.aliases_on = at(1).parse::().is_ok_and(|n| n > 0); } else if r.aliases_on { r.aliases.push(at(1).to_string()); } @@ -1625,6 +1626,9 @@ pub(crate) mod tests { // A table without its count line is rejected: no alias applies. let broken = AffixDict::from_hunspell("SET UTF-8\nAF B\nAF C\nSFX B Y 1\nSFX B 0 s .\n", "2\nlab/1\nfal/2\n", &[]).unwrap(); assert!(broken.check("lab") && !broken.check("labs") && !broken.check("fals")); + // `AF 0` is rejected the same way: `lab/B` keeps its literal flag. + let zero = AffixDict::from_hunspell("SET UTF-8\nAF 0\nSFX B Y 1\nSFX B 0 s .\n", "1\nlab/B\n", &[]).unwrap(); + assert!(zero.check("lab") && zero.check("labs")); // An undefined alias in a continuation class leaves the rule in force, without it. let cont = AffixDict::from_hunspell("SET UTF-8\nAF 1\nAF a\nSFX a Y 1\nSFX a 0 ok/7 .\n", "1\nhaz/1\n", &[]).unwrap(); assert!(cont.check("haz") && cont.check("hazok"));