diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 7377e3ad12d..783f87ce747 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -156,6 +156,9 @@ Bug fixes * LUCENE-5507: Fix HunspellStemFilter loading of dictionaries with large amounts of aliases etc before the encoding declaration. (Robert Muir) +* LUCENE-5502: Fixed TermsFilter.equals that could return true for different + filters. (Igor Motov via Adrien Grand) + Test Framework * LUCENE-5449: Rename _TestUtil and _TestHelper to remove the leading _. diff --git a/lucene/queries/src/java/org/apache/lucene/queries/TermsFilter.java b/lucene/queries/src/java/org/apache/lucene/queries/TermsFilter.java index 4dc88222f8f..9c83dbce3ae 100644 --- a/lucene/queries/src/java/org/apache/lucene/queries/TermsFilter.java +++ b/lucene/queries/src/java/org/apache/lucene/queries/TermsFilter.java @@ -222,24 +222,14 @@ public final class TermsFilter extends Filter { } TermsFilter test = (TermsFilter) obj; - if (test.hashCode == hashCode && this.termsAndFields.length == test.termsAndFields.length) { - // first check the fields before even comparing the bytes - for (int i = 0; i < termsAndFields.length; i++) { - TermsAndField current = termsAndFields[i]; - if (!current.equals(test.termsAndFields[i])) { - return false; - } + // first check the fields before even comparing the bytes + if (test.hashCode == hashCode && Arrays.equals(termsAndFields, test.termsAndFields)) { + int lastOffset = termsAndFields[termsAndFields.length - 1].end; + // compare offsets since we sort they must be identical + if (ArrayUtil.equals(offsets, 0, test.offsets, 0, lastOffset + 1)) { + // straight byte comparison since we sort they must be identical + return ArrayUtil.equals(termsBytes, 0, test.termsBytes, 0, offsets[lastOffset]); } - // straight byte comparison since we sort they must be identical - int end = offsets[termsAndFields.length]; - byte[] left = this.termsBytes; - byte[] right = test.termsBytes; - for(int i=0;i < end;i++) { - if (left[i] != right[i]) { - return false; - } - } - return true; } return false; } diff --git a/lucene/queries/src/test/org/apache/lucene/queries/TermsFilterTest.java b/lucene/queries/src/test/org/apache/lucene/queries/TermsFilterTest.java index 2a071180639..c25e5b2cd82 100644 --- a/lucene/queries/src/test/org/apache/lucene/queries/TermsFilterTest.java +++ b/lucene/queries/src/test/org/apache/lucene/queries/TermsFilterTest.java @@ -50,7 +50,6 @@ import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.FixedBitSet; import org.apache.lucene.util.LuceneTestCase; import org.apache.lucene.util.TestUtil; -import org.apache.lucene.util.TestUtil; public class TermsFilterTest extends LuceneTestCase { @@ -297,7 +296,15 @@ public class TermsFilterTest extends LuceneTestCase { } } } - + + public void testSingleFieldEquals() { + // Two terms with the same hash code + assertEquals("AaAaBB".hashCode(), "BBBBBB".hashCode()); + TermsFilter left = termsFilter(true, new Term("id", "AaAaAa"), new Term("id", "AaAaBB")); + TermsFilter right = termsFilter(true, new Term("id", "AaAaAa"), new Term("id", "BBBBBB")); + assertFalse(left.equals(right)); + } + public void testNoTerms() { List emptyTerms = Collections.emptyList(); List emptyBytesRef = Collections.emptyList();