| Index: src/test/org/apache/lucene/index/TestIndexWriter.java |
| =================================================================== |
| --- src/test/org/apache/lucene/index/TestIndexWriter.java (revision 641983) |
| +++ src/test/org/apache/lucene/index/TestIndexWriter.java (working copy) |
| @@ -30,6 +30,7 @@ |
| import org.apache.lucene.analysis.WhitespaceAnalyzer; |
| import org.apache.lucene.analysis.WhitespaceTokenizer; |
| import org.apache.lucene.analysis.Analyzer; |
| +import org.apache.lucene.analysis.SinkTokenizer; |
| import org.apache.lucene.analysis.TokenFilter; |
| import org.apache.lucene.analysis.TokenStream; |
| import org.apache.lucene.analysis.standard.StandardAnalyzer; |
| @@ -40,6 +41,9 @@ |
| import org.apache.lucene.search.IndexSearcher; |
| import org.apache.lucene.search.Hits; |
| import org.apache.lucene.search.TermQuery; |
| +import org.apache.lucene.search.Query; |
| +import org.apache.lucene.search.spans.SpanTermQuery; |
| +import org.apache.lucene.search.PhraseQuery; |
| import org.apache.lucene.store.Directory; |
| import org.apache.lucene.store.FSDirectory; |
| import org.apache.lucene.store.RAMDirectory; |
| @@ -3549,4 +3553,46 @@ |
| assertEquals(expected[i], utf16a.result[i]); |
| } |
| } |
| + |
| + // LUCENE-1255 |
| + public void testNegativePositions() throws Throwable { |
| + SinkTokenizer tokens = new SinkTokenizer(); |
| + Token t = new Token(); |
| + t.setTermText("a"); |
| + t.setPositionIncrement(0); |
| + tokens.add(t); |
| + t.setTermText("b"); |
| + t.setPositionIncrement(1); |
| + tokens.add(t); |
| + t.setTermText("c"); |
| + tokens.add(t); |
| + |
| + MockRAMDirectory dir = new MockRAMDirectory(); |
| + IndexWriter w = new IndexWriter(dir, false, new WhitespaceAnalyzer(), true, IndexWriter.MaxFieldLength.UNLIMITED); |
| + Document doc = new Document(); |
| + doc.add(new Field("field", tokens)); |
| + w.addDocument(doc); |
| + w.commit(); |
| + |
| + IndexSearcher s = new IndexSearcher(dir); |
| + PhraseQuery pq = new PhraseQuery(); |
| + pq.add(new Term("field", "a")); |
| + pq.add(new Term("field", "b")); |
| + pq.add(new Term("field", "c")); |
| + Hits hits = s.search(pq); |
| + assertEquals(1, hits.length()); |
| + |
| + Query q = new SpanTermQuery(new Term("field", "a")); |
| + hits = s.search(q); |
| + assertEquals(1, hits.length()); |
| + TermPositions tps = s.getIndexReader().termPositions(new Term("field", "a")); |
| + assertTrue(tps.next()); |
| + assertEquals(1, tps.freq()); |
| + assertEquals(0, tps.nextPosition()); |
| + w.close(); |
| + |
| + assertTrue(_TestUtil.checkIndex(dir)); |
| + s.close(); |
| + dir.close(); |
| + } |
| } |
| Index: src/java/org/apache/lucene/index/DocumentsWriterFieldData.java |
| =================================================================== |
| --- src/java/org/apache/lucene/index/DocumentsWriterFieldData.java (revision 642934) |
| +++ src/java/org/apache/lucene/index/DocumentsWriterFieldData.java (working copy) |
| @@ -239,11 +239,13 @@ |
| |
| try { |
| offsetEnd = offset-1; |
| - Token token; |
| for(;;) { |
| - token = stream.next(localToken); |
| + Token token = stream.next(localToken); |
| if (token == null) break; |
| position += (token.getPositionIncrement() - 1); |
| + // LUCENE-1255: don't allow negative positon |
| + if (position < 0) |
| + position = 0; |
| addPosition(token); |
| if (++length >= maxFieldLength) { |
| if (threadState.docWriter.infoStream != null) |
| Index: src/java/org/apache/lucene/index/IndexWriter.java |
| =================================================================== |
| --- src/java/org/apache/lucene/index/IndexWriter.java (revision 641983) |
| +++ src/java/org/apache/lucene/index/IndexWriter.java (working copy) |
| @@ -1692,8 +1692,11 @@ |
| throw oom; |
| } finally { |
| synchronized(this) { |
| - if (!closed) |
| + if (!closed) { |
| closing = false; |
| + if (infoStream != null) |
| + message("hit exception while closing"); |
| + } |
| notifyAll(); |
| } |
| } |
| Index: src/java/org/apache/lucene/index/CheckIndex.java |
| =================================================================== |
| --- src/java/org/apache/lucene/index/CheckIndex.java (revision 641983) |
| +++ src/java/org/apache/lucene/index/CheckIndex.java (working copy) |
| @@ -223,7 +223,7 @@ |
| final int pos = termPositions.nextPosition(); |
| if (pos < 0) |
| throw new RuntimeException("term " + term + ": doc " + doc + ": pos " + pos + " is out of bounds"); |
| - if (pos <= lastPos) |
| + if (pos < lastPos) |
| throw new RuntimeException("term " + term + ": doc " + doc + ": pos " + pos + " < lastPos " + lastPos); |
| } |
| } |