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 2012/03/15 20:12:42 UTC

svn commit: r1301155 - in /lucene/dev/trunk/lucene: CHANGES.txt core/src/java/org/apache/lucene/index/DocInverterPerField.java core/src/test/org/apache/lucene/index/TestIndexWriterExceptions.java

Author: rmuir
Date: Thu Mar 15 19:12:41 2012
New Revision: 1301155

URL: http://svn.apache.org/viewvc?rev=1301155&view=rev
Log:
LUCENE-3874: don't let bogus positions corrumpt the index

Modified:
    lucene/dev/trunk/lucene/CHANGES.txt
    lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/index/DocInverterPerField.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterExceptions.java

Modified: lucene/dev/trunk/lucene/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/CHANGES.txt?rev=1301155&r1=1301154&r2=1301155&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/CHANGES.txt (original)
+++ lucene/dev/trunk/lucene/CHANGES.txt Thu Mar 15 19:12:41 2012
@@ -937,6 +937,12 @@ Bug fixes
 * LUCENE-3872: IndexWriter.close() now throws IllegalStateException if
   you call it after calling prepareCommit() without calling commit()
   first.  (Tim Bogaert via Mike McCandless)
+
+* LUCENE-3874: Throw IllegalArgumentException from IndexWriter (rather
+  than producing a corrupt index), if a positionIncrement would cause
+  integer overflow. This can happen, for example when using a buggy
+  TokenStream that forgets to call clearAttributes() in combination
+  with a StopFilter. (Robert Muir)
     
 Optimizations
 

Modified: lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/index/DocInverterPerField.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/index/DocInverterPerField.java?rev=1301155&r1=1301154&r2=1301155&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/index/DocInverterPerField.java (original)
+++ lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/index/DocInverterPerField.java Thu Mar 15 19:12:41 2012
@@ -109,10 +109,16 @@ final class DocInverterPerField extends 
             if (!hasMoreTokens) break;
 
             final int posIncr = posIncrAttribute.getPositionIncrement();
-            fieldState.position += posIncr;
-            if (fieldState.position > 0) {
-              fieldState.position--;
+            int position = fieldState.position + posIncr;
+            if (position > 0) {
+              position--;
+            } else if (position < 0) {
+              throw new IllegalArgumentException("position overflow for field '" + field.name() + "'");
             }
+            
+            // position is legal, we can safely place it in fieldState now.
+            // not sure if anything will use fieldState after non-aborting exc...
+            fieldState.position = position;
 
             if (posIncr == 0)
               fieldState.numOverlap++;

Modified: lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterExceptions.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterExceptions.java?rev=1301155&r1=1301154&r2=1301155&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterExceptions.java (original)
+++ lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterExceptions.java Thu Mar 15 19:12:41 2012
@@ -1494,4 +1494,27 @@ public class TestIndexWriterExceptions e
     uoe.doFail = false;
     d.close();
   }
+  
+  public void testIllegalPositions() throws Exception {
+    Directory dir = newDirectory();
+    IndexWriter iw = new IndexWriter(dir, newIndexWriterConfig(TEST_VERSION_CURRENT, null));
+    Document doc = new Document();
+    Token t1 = new Token("foo", 0, 3);
+    t1.setPositionIncrement(Integer.MAX_VALUE);
+    Token t2 = new Token("bar", 4, 7);
+    t2.setPositionIncrement(200);
+    TokenStream overflowingTokenStream = new CannedTokenStream(
+        new Token[] { t1, t2 }
+    );
+    Field field = new TextField("foo", overflowingTokenStream);
+    doc.add(field);
+    try {
+      iw.addDocument(doc);
+      fail();
+    } catch (IllegalArgumentException expected) {
+      // expected exception
+    }
+    iw.close();
+    dir.close();
+  }
 }