From 9e1fcb0eb47637082d15700a92e52f0b1c155bc7 Mon Sep 17 00:00:00 2001 From: Adrien Grand Date: Tue, 16 May 2017 18:31:57 +0200 Subject: [PATCH] LUCENE-7831: CodecUtil should not seek to negative offsets. --- lucene/CHANGES.txt | 5 ++++- .../java/org/apache/lucene/codecs/CodecUtil.java | 6 ++++++ .../org/apache/lucene/codecs/TestCodecUtil.java | 13 +++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index bbdc7bdfa18..ce6ba678805 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -93,7 +93,10 @@ Other (Daniel Jelinski via Adrien Grand) ======================= Lucene 6.7.0 ======================= -(No Changes) + +Bug Fixes + +* LUCENE-7831: CodecUtil should not seek to negative offsets. (Adrien Grand) ======================= Lucene 6.6.0 ======================= diff --git a/lucene/core/src/java/org/apache/lucene/codecs/CodecUtil.java b/lucene/core/src/java/org/apache/lucene/codecs/CodecUtil.java index a625b47a060..c49946b7ffb 100644 --- a/lucene/core/src/java/org/apache/lucene/codecs/CodecUtil.java +++ b/lucene/core/src/java/org/apache/lucene/codecs/CodecUtil.java @@ -331,6 +331,9 @@ public final class CodecUtil { /** Retrieves the full footer from the provided {@link IndexInput}. This throws * {@link CorruptIndexException} if this file does not have a valid footer. */ public static byte[] readFooter(IndexInput in) throws IOException { + if (in.length() < footerLength()) { + throw new CorruptIndexException("misplaced codec footer (file truncated?): length=" + in.length() + " but footerLength==" + footerLength(), in); + } in.seek(in.length() - footerLength()); validateFooter(in); in.seek(in.length() - footerLength()); @@ -516,6 +519,9 @@ public final class CodecUtil { clone.seek(0); ChecksumIndexInput in = new BufferedChecksumIndexInput(clone); assert in.getFilePointer() == 0; + if (in.length() < footerLength()) { + throw new CorruptIndexException("misplaced codec footer (file truncated?): length=" + in.length() + " but footerLength==" + footerLength(), input); + } in.seek(in.length() - footerLength()); return checkFooter(in); } diff --git a/lucene/core/src/test/org/apache/lucene/codecs/TestCodecUtil.java b/lucene/core/src/test/org/apache/lucene/codecs/TestCodecUtil.java index d403f81b54f..0ff7f7c9cf8 100644 --- a/lucene/core/src/test/org/apache/lucene/codecs/TestCodecUtil.java +++ b/lucene/core/src/test/org/apache/lucene/codecs/TestCodecUtil.java @@ -303,4 +303,17 @@ public class TestCodecUtil extends LuceneTestCase { fakeChecksum.set((1L << 32) - 1); // ok CodecUtil.writeCRC(fakeOutput); } + + public void testTruncatedFileThrowsCorruptIndexException() throws IOException { + RAMFile file = new RAMFile(); + IndexOutput output = new RAMOutputStream(file, false); + output.close(); + IndexInput input = new RAMInputStream("file", file); + CorruptIndexException e = expectThrows(CorruptIndexException.class, + () -> CodecUtil.checksumEntireFile(input)); + assertEquals("misplaced codec footer (file truncated?): length=0 but footerLength==16 (resource=RAMInputStream(name=file))", e.getMessage()); + e = expectThrows(CorruptIndexException.class, + () -> CodecUtil.retrieveChecksum(input)); + assertEquals("misplaced codec footer (file truncated?): length=0 but footerLength==16 (resource=RAMInputStream(name=file))", e.getMessage()); + } }