You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@solr.apache.org by kr...@apache.org on 2022/04/27 19:33:43 UTC
[solr] branch main updated: SOLR-16169: IndexBasedSpellChecker with empty spellcheck.q results in NegativeArraySizeException (#820)
This is an automated email from the ASF dual-hosted git repository.
krisden pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/solr.git
The following commit(s) were added to refs/heads/main by this push:
new 6510f14a267 SOLR-16169: IndexBasedSpellChecker with empty spellcheck.q results in NegativeArraySizeException (#820)
6510f14a267 is described below
commit 6510f14a267835f2f7aa4f795714d162eb3a0c82
Author: Kevin Risden <ri...@users.noreply.github.com>
AuthorDate: Wed Apr 27 15:33:39 2022 -0400
SOLR-16169: IndexBasedSpellChecker with empty spellcheck.q results in NegativeArraySizeException (#820)
---
solr/CHANGES.txt | 2 ++
.../solr/spelling/AbstractLuceneSpellChecker.java | 4 +++
.../solr/spelling/DirectSolrSpellChecker.java | 4 +++
.../solr/spelling/DirectSolrSpellCheckerTest.java | 13 ++++++--
.../solr/spelling/FileBasedSpellCheckerTest.java | 38 ++++++++++++++--------
.../solr/spelling/IndexBasedSpellCheckerTest.java | 9 +++++
6 files changed, 55 insertions(+), 15 deletions(-)
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 484631dda9f..42f8813e54f 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -71,6 +71,8 @@ Bug Fixes
* SOLR-15830: Concurrent core reloads mess up commits when using Schema API (Bence Szabo via Andras Salamon)
+* SOLR-16169: IndexBasedSpellChecker with empty spellcheck.q results in NegativeArraySizeException (Kevin Risden)
+
Other Changes
---------------------
* SOLR-15897: Remove <jmx/> from all unit test solrconfig.xml files. (Eric Pugh)
diff --git a/solr/core/src/java/org/apache/solr/spelling/AbstractLuceneSpellChecker.java b/solr/core/src/java/org/apache/solr/spelling/AbstractLuceneSpellChecker.java
index 1af07e16388..0ddb6149421 100644
--- a/solr/core/src/java/org/apache/solr/spelling/AbstractLuceneSpellChecker.java
+++ b/solr/core/src/java/org/apache/solr/spelling/AbstractLuceneSpellChecker.java
@@ -141,6 +141,10 @@ public abstract class AbstractLuceneSpellChecker extends SolrSpellChecker {
int count = Math.max(options.count, AbstractLuceneSpellChecker.DEFAULT_SUGGESTION_COUNT);
for (Token token : options.tokens) {
+ if (token.length() == 0) {
+ result.add(token, Collections.emptyList());
+ continue;
+ }
String tokenText = new String(token.buffer(), 0, token.length());
term = new Term(field, tokenText);
int docFreq = 0;
diff --git a/solr/core/src/java/org/apache/solr/spelling/DirectSolrSpellChecker.java b/solr/core/src/java/org/apache/solr/spelling/DirectSolrSpellChecker.java
index 25f9f1218c1..04b8bec49e4 100644
--- a/solr/core/src/java/org/apache/solr/spelling/DirectSolrSpellChecker.java
+++ b/solr/core/src/java/org/apache/solr/spelling/DirectSolrSpellChecker.java
@@ -186,6 +186,10 @@ public class DirectSolrSpellChecker extends SolrSpellChecker {
(options.accuracy == Float.MIN_VALUE) ? checker.getAccuracy() : options.accuracy;
for (Token token : options.tokens) {
+ if (token.length() == 0) {
+ result.add(token, Collections.emptyList());
+ continue;
+ }
String tokenText = token.toString();
Term term = new Term(field, tokenText);
int freq = options.reader.docFreq(term);
diff --git a/solr/core/src/test/org/apache/solr/spelling/DirectSolrSpellCheckerTest.java b/solr/core/src/test/org/apache/solr/spelling/DirectSolrSpellCheckerTest.java
index 9e1e192f566..5aff7b50b8f 100644
--- a/solr/core/src/test/org/apache/solr/spelling/DirectSolrSpellCheckerTest.java
+++ b/solr/core/src/test/org/apache/solr/spelling/DirectSolrSpellCheckerTest.java
@@ -17,6 +17,7 @@
package org.apache.solr.spelling;
import java.util.Collection;
+import java.util.Collections;
import java.util.Map;
import org.apache.lucene.util.LuceneTestCase.SuppressTempFileChecks;
import org.apache.solr.SolrTestCaseJ4;
@@ -70,7 +71,7 @@ public class DirectSolrSpellCheckerTest extends SolrTestCaseJ4 {
SpellingOptions spellOpts = new SpellingOptions(tokens, searcher.getIndexReader());
SpellingResult result = checker.getSuggestions(spellOpts);
assertNotNull("result shouldn't be null", result);
- Map<String, Integer> suggestions = result.get(tokens.iterator().next());
+ Map<String, Integer> suggestions = result.get(spellOpts.tokens.iterator().next());
assertFalse("suggestions shouldn't be empty", suggestions.isEmpty());
Map.Entry<String, Integer> entry = suggestions.entrySet().iterator().next();
assertEquals("foo", entry.getKey());
@@ -85,6 +86,14 @@ public class DirectSolrSpellCheckerTest extends SolrTestCaseJ4 {
suggestions = result.get(spellOpts.tokens.iterator().next());
assertNotNull("suggestions shouldn't be null", suggestions);
assertTrue("suggestions should be empty", suggestions.isEmpty());
+
+ // Check empty token due to spellcheck.q = ""
+ spellOpts.tokens = Collections.singletonList(new Token("", 0, 0));
+ result = checker.getSuggestions(spellOpts);
+ assertNotNull("result shouldn't be null", result);
+ suggestions = result.get(spellOpts.tokens.iterator().next());
+ assertNotNull("suggestions shouldn't be null", suggestions);
+ assertTrue("suggestions should be empty", suggestions.isEmpty());
return null;
});
}
@@ -138,7 +147,7 @@ public class DirectSolrSpellCheckerTest extends SolrTestCaseJ4 {
SpellingOptions spellOpts = new SpellingOptions(tokens, searcher.getIndexReader());
SpellingResult result = checker.getSuggestions(spellOpts);
assertNotNull("result shouldn't be null", result);
- Map<String, Integer> suggestions = result.get(tokens.iterator().next());
+ Map<String, Integer> suggestions = result.get(spellOpts.tokens.iterator().next());
assertNotNull("suggestions shouldn't be null", suggestions);
if (limitQueryLength) {
diff --git a/solr/core/src/test/org/apache/solr/spelling/FileBasedSpellCheckerTest.java b/solr/core/src/test/org/apache/solr/spelling/FileBasedSpellCheckerTest.java
index a7569d85268..ee3aa8a57f1 100644
--- a/solr/core/src/test/org/apache/solr/spelling/FileBasedSpellCheckerTest.java
+++ b/solr/core/src/test/org/apache/solr/spelling/FileBasedSpellCheckerTest.java
@@ -18,6 +18,7 @@ package org.apache.solr.spelling;
import java.io.File;
import java.util.Collection;
+import java.util.Collections;
import java.util.Map;
import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.util.LuceneTestCase.SuppressTempFileChecks;
@@ -80,8 +81,8 @@ public class FileBasedSpellCheckerTest extends SolrTestCaseJ4 {
Collection<Token> tokens = queryConverter.convert("fob");
SpellingOptions spellOpts = new SpellingOptions(tokens, searcher.getIndexReader());
SpellingResult result = checker.getSuggestions(spellOpts);
- assertTrue("result is null and it shouldn't be", result != null);
- Map<String, Integer> suggestions = result.get(tokens.iterator().next());
+ assertNotNull("result shouldn't be null", result);
+ Map<String, Integer> suggestions = result.get(spellOpts.tokens.iterator().next());
Map.Entry<String, Integer> entry = suggestions.entrySet().iterator().next();
assertTrue(
entry.getKey() + " is not equal to " + "foo",
@@ -92,9 +93,18 @@ public class FileBasedSpellCheckerTest extends SolrTestCaseJ4 {
spellOpts.tokens = queryConverter.convert("super");
result = checker.getSuggestions(spellOpts);
- assertTrue("result is null and it shouldn't be", result != null);
- suggestions = result.get(tokens.iterator().next());
- assertTrue("suggestions is not null and it should be", suggestions == null);
+ assertNotNull("result shouldn't be null", result);
+ suggestions = result.get(spellOpts.tokens.iterator().next());
+ assertNotNull("suggestions shouldn't be null", suggestions);
+ assertTrue("suggestions should be empty", suggestions.isEmpty());
+
+ // Check empty token due to spellcheck.q = ""
+ spellOpts.tokens = Collections.singletonList(new Token("", 0, 0));
+ result = checker.getSuggestions(spellOpts);
+ assertNotNull("result shouldn't be null", result);
+ suggestions = result.get(spellOpts.tokens.iterator().next());
+ assertNotNull("suggestions shouldn't be null", suggestions);
+ assertTrue("suggestions should be empty", suggestions.isEmpty());
return null;
});
}
@@ -125,7 +135,7 @@ public class FileBasedSpellCheckerTest extends SolrTestCaseJ4 {
SpellingResult result = checker.getSuggestions(spellOpts);
assertTrue("result is null and it shouldn't be", result != null);
// should be lowercased, b/c we are using a lowercasing analyzer
- Map<String, Integer> suggestions = result.get(tokens.iterator().next());
+ Map<String, Integer> suggestions = result.get(spellOpts.tokens.iterator().next());
assertTrue(
"suggestions Size: " + suggestions.size() + " is not: " + 1,
suggestions.size() == 1);
@@ -140,9 +150,10 @@ public class FileBasedSpellCheckerTest extends SolrTestCaseJ4 {
// test something not in the spell checker
spellOpts.tokens = queryConverter.convert("super");
result = checker.getSuggestions(spellOpts);
- assertTrue("result is null and it shouldn't be", result != null);
- suggestions = result.get(tokens.iterator().next());
- assertTrue("suggestions is not null and it should be", suggestions == null);
+ assertNotNull("result shouldn't be null", result);
+ suggestions = result.get(spellOpts.tokens.iterator().next());
+ assertNotNull("suggestions shouldn't be null", suggestions);
+ assertTrue("suggestions should be empty", suggestions.isEmpty());
return null;
});
}
@@ -172,9 +183,9 @@ public class FileBasedSpellCheckerTest extends SolrTestCaseJ4 {
Collection<Token> tokens = queryConverter.convert("solar");
SpellingOptions spellOpts = new SpellingOptions(tokens, searcher.getIndexReader());
SpellingResult result = checker.getSuggestions(spellOpts);
- assertTrue("result is null and it shouldn't be", result != null);
+ assertNotNull("result shouldn't be null", result);
// should be lowercased, b/c we are using a lowercasing analyzer
- Map<String, Integer> suggestions = result.get(tokens.iterator().next());
+ Map<String, Integer> suggestions = result.get(spellOpts.tokens.iterator().next());
assertTrue(
"suggestions Size: " + suggestions.size() + " is not: " + 1,
suggestions.size() == 1);
@@ -188,9 +199,10 @@ public class FileBasedSpellCheckerTest extends SolrTestCaseJ4 {
spellOpts.tokens = queryConverter.convert("super");
result = checker.getSuggestions(spellOpts);
- assertTrue("result is null and it shouldn't be", result != null);
+ assertNotNull("result shouldn't be null", result);
suggestions = result.get(spellOpts.tokens.iterator().next());
- assertTrue("suggestions size should be 0", suggestions.size() == 0);
+ assertNotNull("suggestions shouldn't be null", suggestions);
+ assertTrue("suggestions should be empty", suggestions.isEmpty());
return null;
});
}
diff --git a/solr/core/src/test/org/apache/solr/spelling/IndexBasedSpellCheckerTest.java b/solr/core/src/test/org/apache/solr/spelling/IndexBasedSpellCheckerTest.java
index 4f82333e557..dfb640cba79 100644
--- a/solr/core/src/test/org/apache/solr/spelling/IndexBasedSpellCheckerTest.java
+++ b/solr/core/src/test/org/apache/solr/spelling/IndexBasedSpellCheckerTest.java
@@ -18,6 +18,7 @@ package org.apache.solr.spelling;
import java.io.File;
import java.util.Collection;
+import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.Map;
@@ -188,6 +189,14 @@ public class IndexBasedSpellCheckerTest extends SolrTestCaseJ4 {
assertTrue(
entry.getValue() + " does not equal: " + SpellingResult.NO_FREQUENCY_INFO,
entry.getValue() == SpellingResult.NO_FREQUENCY_INFO);
+
+ // Check empty token due to spellcheck.q = ""
+ spellOpts.tokens = Collections.singletonList(new Token("", 0, 0));
+ result = checker.getSuggestions(spellOpts);
+ assertNotNull(result);
+ suggestions = result.get(spellOpts.tokens.iterator().next());
+ assertNotNull(suggestions);
+ assertTrue("suggestions should be empty", suggestions.isEmpty());
return null;
});
}