You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by rm...@apache.org on 2025/02/15 13:52:19 UTC
(lucene) branch branch_10x updated: hunspell: improve tolerateAffixRuleCountMismatches() for common problems (#14239)
This is an automated email from the ASF dual-hosted git repository.
rmuir pushed a commit to branch branch_10x
in repository https://gitbox.apache.org/repos/asf/lucene.git
The following commit(s) were added to refs/heads/branch_10x by this push:
new 24057d851d9 hunspell: improve tolerateAffixRuleCountMismatches() for common problems (#14239)
24057d851d9 is described below
commit 24057d851d9c02867886750d1740aad4104e7195
Author: Robert Muir <rm...@apache.org>
AuthorDate: Sat Feb 15 08:42:03 2025 -0500
hunspell: improve tolerateAffixRuleCountMismatches() for common problems (#14239)
When the user opts-in to tolerateAffixRuleCountMismatches(), it tolerates
some, but not all affix mismatches. Support two cases:
"EOF case": count is wrong and then we encounter end of file.
previously the exception looked like this:
java.text.ParseException: Premature end of rules for SFX B Y 2
"stampede case": in this case count is wrong and another instruction
follows (such as another affix's rule).
Previously, the exception looked like this:
java.text.ParseException: Affix rule mismatch. Header: SFX A Y 2; rule: SFX B Y 2
---
lucene/CHANGES.txt | 3 +++
.../java/org/apache/lucene/analysis/hunspell/Dictionary.java | 11 +++++++++++
.../org/apache/lucene/analysis/hunspell/TestDictionary.java | 11 +++++++++++
.../org/apache/lucene/analysis/hunspell/common-errors.aff | 9 +++++++++
.../org/apache/lucene/analysis/hunspell/common-errors.dic | 9 +++++++++
5 files changed, 43 insertions(+)
diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index 982c3b67dce..7712a87b536 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -48,6 +48,9 @@ Improvements
the wrapped analyzer's strategy to decide if components can be reused or need
to be updated. (Mayya Sharipova)
+* GITHUB#14239: Hunspell's option to tolerate affix rule count mismatches was
+ improved to tolerate more instances of this problem. (Robert Muir)
+
Optimizations
---------------------
diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/hunspell/Dictionary.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/hunspell/Dictionary.java
index fc5353560b5..4d1b7a8192e 100644
--- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/hunspell/Dictionary.java
+++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/hunspell/Dictionary.java
@@ -708,8 +708,15 @@ public class Dictionary {
affixData = ArrayUtil.grow(affixData, currentAffix * 4 + numLines * 4);
for (int i = 0; i < numLines; i++) {
+ if (tolerateAffixRuleCountMismatches()) {
+ // push back line if counts are wrong, with a limit: forgiveness is finite.
+ reader.mark(256);
+ }
String line = reader.readLine();
if (line == null) {
+ if (tolerateAffixRuleCountMismatches()) {
+ return; // can happen due to rule count mismatches, EOF
+ }
throw new ParseException("Premature end of rules for " + header, reader.getLineNumber());
}
@@ -717,6 +724,10 @@ public class Dictionary {
String[] ruleArgs = splitBySpace(reader, line, 4, Integer.MAX_VALUE);
if (!ruleArgs[1].equals(args[1])) {
+ if (tolerateAffixRuleCountMismatches()) {
+ reader.reset(); // can happen due to count mismatch: push back what we found
+ return;
+ }
throw new ParseException(
"Affix rule mismatch. Header: " + header + "; rule: " + line, reader.getLineNumber());
}
diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/hunspell/TestDictionary.java b/lucene/analysis/common/src/test/org/apache/lucene/analysis/hunspell/TestDictionary.java
index 1aab0164121..481a3dc0aae 100644
--- a/lucene/analysis/common/src/test/org/apache/lucene/analysis/hunspell/TestDictionary.java
+++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/hunspell/TestDictionary.java
@@ -188,6 +188,17 @@ public class TestDictionary extends LuceneTestCase {
loadForgivingDictionary("forgivable-errors-num.aff", "single-word.dic");
}
+ /** simple tests for dictionary problems seen in the wild */
+ public void testCommonForgivableErrors() throws Exception {
+ Dictionary dictionary = loadForgivingDictionary("common-errors.aff", "common-errors.dic");
+ // try to ensure we still parsed the affixes correctly, despite the problems
+ String expectedSuffixes[] = {"ing", "ed"};
+ for (String suffix : expectedSuffixes) {
+ char reversed[] = new StringBuilder(suffix).reverse().toString().toCharArray();
+ assertNotNull("checking for " + suffix, dictionary.lookupSuffix(reversed));
+ }
+ }
+
private Dictionary loadDictionary(String aff, String dic) throws IOException, ParseException {
try (InputStream affixStream = getClass().getResourceAsStream(aff);
InputStream dicStream = getClass().getResourceAsStream(dic);
diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/hunspell/common-errors.aff b/lucene/analysis/common/src/test/org/apache/lucene/analysis/hunspell/common-errors.aff
new file mode 100644
index 00000000000..6b061e99c16
--- /dev/null
+++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/hunspell/common-errors.aff
@@ -0,0 +1,9 @@
+SET UTF-8
+
+# add some suffix off-by-ones here, feel free to add more
+# SFX A: wrong count, come up short on entries and stampede into SFX B.
+# SFX B: wrong count, hit EOF
+SFX A Y 2
+SFX A 0 ing .
+SFX B Y 2
+SFX B 0 ed .
diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/hunspell/common-errors.dic b/lucene/analysis/common/src/test/org/apache/lucene/analysis/hunspell/common-errors.dic
new file mode 100644
index 00000000000..48506b98960
--- /dev/null
+++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/hunspell/common-errors.dic
@@ -0,0 +1,9 @@
+# Dictionary for testing common mistakes to tolerate in dictionaries.
+# Purpose is to test that we still behave well even with the common mistakes.
+# Lucene parser seems to be really strict with these numbers.
+# I wonder if we should just ignore them entirely and parse in a different way?
+# Have the suspicion that maybe C hunspell just uses them as a "hint" to size data?
+# Add more flags if you need to the "testword" for any more affix bugs found.
+# Or add more words if the problem is instead around this file.
+1
+testword/AB