lucene-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rm...@apache.org
Subject svn commit: r1685927 - in /lucene/dev/trunk/lucene: CHANGES.txt core/src/java/org/apache/lucene/codecs/CodecUtil.java core/src/test/org/apache/lucene/index/TestCodecUtil.java
Date Wed, 17 Jun 2015 02:49:35 GMT
Author: rmuir
Date: Wed Jun 17 02:49:35 2015
New Revision: 1685927

URL: http://svn.apache.org/r1685927
Log:
LUCENE-6577: Give earlier and better error message for invalid CRC

Modified:
    lucene/dev/trunk/lucene/CHANGES.txt
    lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/codecs/CodecUtil.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestCodecUtil.java

Modified: lucene/dev/trunk/lucene/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/CHANGES.txt?rev=1685927&r1=1685926&r2=1685927&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/CHANGES.txt (original)
+++ lucene/dev/trunk/lucene/CHANGES.txt Wed Jun 17 02:49:35 2015
@@ -85,6 +85,9 @@ New Features
   quite slow and are only fast in specific cases.  (Adrien Grand,
   Robert Muir, Mike McCandless)
 
+* LUCENE-6577: Give earlier and better error message for invalid CRC.
+  (Robert Muir)
+
 API Changes
 
 * LUCENE-6508: Simplify Lock api, there is now just 

Modified: lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/codecs/CodecUtil.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/codecs/CodecUtil.java?rev=1685927&r1=1685926&r2=1685927&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/codecs/CodecUtil.java (original)
+++ lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/codecs/CodecUtil.java Wed Jun
17 02:49:35 2015
@@ -307,7 +307,7 @@ public final class CodecUtil {
   public static void writeFooter(IndexOutput out) throws IOException {
     out.writeInt(FOOTER_MAGIC);
     out.writeInt(0);
-    out.writeLong(out.getChecksum());
+    writeCRC(out);
   }
   
   /**
@@ -330,7 +330,7 @@ public final class CodecUtil {
   public static long checkFooter(ChecksumIndexInput in) throws IOException {
     validateFooter(in);
     long actualChecksum = in.getChecksum();
-    long expectedChecksum = in.readLong();
+    long expectedChecksum = readCRC(in);
     if (expectedChecksum != actualChecksum) {
       throw new CorruptIndexException("checksum failed (hardware problem?) : expected=" +
Long.toHexString(expectedChecksum) +  
                                                        " actual=" + Long.toHexString(actualChecksum),
in);
@@ -399,7 +399,7 @@ public final class CodecUtil {
   public static long retrieveChecksum(IndexInput in) throws IOException {
     in.seek(in.length() - footerLength());
     validateFooter(in);
-    return in.readLong();
+    return readCRC(in);
   }
   
   private static void validateFooter(IndexInput in) throws IOException {
@@ -436,4 +436,30 @@ public final class CodecUtil {
     in.seek(in.length() - footerLength());
     return checkFooter(in);
   }
+  
+  /**
+   * Reads CRC32 value as a 64-bit long from the input.
+   * @throws CorruptIndexException if CRC is formatted incorrectly (wrong bits set)
+   * @throws IOException if an i/o error occurs
+   */
+  public static long readCRC(IndexInput input) throws IOException {
+    long value = input.readLong();
+    if ((value & 0xFFFFFFFF00000000L) != 0) {
+      throw new CorruptIndexException("Illegal CRC-32 checksum: " + value, input);
+    }
+    return value;
+  }
+  
+  /**
+   * Writes CRC32 value as a 64-bit long to the output.
+   * @throws IllegalStateException if CRC is formatted incorrectly (wrong bits set)
+   * @throws IOException if an i/o error occurs
+   */
+  public static void writeCRC(IndexOutput output) throws IOException {
+    long value = output.getChecksum();
+    if ((value & 0xFFFFFFFF00000000L) != 0) {
+      throw new IllegalStateException("Illegal CRC-32 checksum: " + value + " (resource="
+ output + ")");
+    }
+    output.writeLong(value);
+  }
 }

Modified: lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestCodecUtil.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestCodecUtil.java?rev=1685927&r1=1685926&r2=1685927&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestCodecUtil.java (original)
+++ lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestCodecUtil.java Wed Jun
17 02:49:35 2015
@@ -17,6 +17,9 @@ package org.apache.lucene.index;
  * limitations under the License.
  */
 
+import java.io.IOException;
+import java.util.concurrent.atomic.AtomicLong;
+
 import org.apache.lucene.codecs.CodecUtil;
 import org.apache.lucene.store.BufferedChecksumIndexInput;
 import org.apache.lucene.store.ChecksumIndexInput;
@@ -252,4 +255,86 @@ public class TestCodecUtil extends Lucen
       // expected
     }
   }
+  
+  public void testReadBogusCRC() throws Exception {
+    RAMFile file = new RAMFile();
+    IndexOutput output = new RAMOutputStream(file, false);
+    output.writeLong(-1L); // bad
+    output.writeLong(1L << 32); // bad
+    output.writeLong(-(1L << 32)); // bad
+    output.writeLong((1L << 32) - 1); // ok
+    output.close();
+    IndexInput input = new RAMInputStream("file", file);
+    // read 3 bogus values
+    for (int i = 0; i < 3; i++) {
+      try {
+        CodecUtil.readCRC(input);
+        fail("didn't get expected exception");
+      } catch (CorruptIndexException expected) {
+        // expected
+      }
+    }
+    // good value
+    CodecUtil.readCRC(input);
+  }
+  
+  public void testWriteBogusCRC() throws Exception {
+    RAMFile file = new RAMFile();
+    final IndexOutput output = new RAMOutputStream(file, false);
+    AtomicLong fakeChecksum = new AtomicLong();
+    // wrap the index input where we control the checksum for mocking
+    IndexOutput fakeOutput = new IndexOutput("fake") {
+      @Override
+      public void close() throws IOException {
+        output.close();
+      }
+
+      @Override
+      public long getFilePointer() {
+        return output.getFilePointer();
+      }
+
+      @Override
+      public long getChecksum() throws IOException {
+        return fakeChecksum.get();
+      }
+
+      @Override
+      public void writeByte(byte b) throws IOException {
+        output.writeByte(b);
+      }
+
+      @Override
+      public void writeBytes(byte[] b, int offset, int length) throws IOException {
+        output.writeBytes(b, offset, length);
+      }
+    };
+    
+    fakeChecksum.set(-1L); // bad
+    try {
+      CodecUtil.writeCRC(fakeOutput);
+      fail("didn't get expected exception");
+    } catch (IllegalStateException expected) {
+      // expected exception
+    }
+    
+    fakeChecksum.set(1L << 32); // bad
+    try {
+      CodecUtil.writeCRC(fakeOutput);
+      fail("didn't get expected exception");
+    } catch (IllegalStateException expected) {
+      // expected exception
+    }
+    
+    fakeChecksum.set(-(1L << 32)); // bad
+    try {
+      CodecUtil.writeCRC(fakeOutput);
+      fail("didn't get expected exception");
+    } catch (IllegalStateException expected) {
+      // expected exception
+    }
+    
+    fakeChecksum.set((1L << 32) - 1); // ok
+    CodecUtil.writeCRC(fakeOutput);
+  }
 }



Mime
View raw message