LUCENE-9161: DirectMonotonicWriter checks for overflows. (#1197)

This commit is contained in:
Adrien Grand 2020-01-28 19:06:53 +01:00 committed by GitHub
parent 6eb8834a57
commit 92b684c647
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 3 deletions

View File

@ -21,6 +21,7 @@ package org.apache.lucene.util.packed;
import java.io.IOException;
import org.apache.lucene.store.IndexOutput;
import org.apache.lucene.util.ArrayUtil;
/**
* Write monotonically-increasing sequences of integers. This writer splits
@ -46,12 +47,20 @@ public final class DirectMonotonicWriter {
boolean finished;
DirectMonotonicWriter(IndexOutput metaOut, IndexOutput dataOut, long numValues, int blockShift) {
if (blockShift < MIN_BLOCK_SHIFT || blockShift > MAX_BLOCK_SHIFT) {
throw new IllegalArgumentException("blockShift must be in [" + MIN_BLOCK_SHIFT + "-" + MAX_BLOCK_SHIFT + "], got " + blockShift);
}
if (numValues < 0) {
throw new IllegalArgumentException("numValues can't be negative, got " + numValues);
}
final long numBlocks = numValues == 0 ? 0 : ((numValues - 1) >>> blockShift) + 1;
if (numBlocks > ArrayUtil.MAX_ARRAY_LENGTH) {
throw new IllegalArgumentException("blockShift is too low for the provided number of values: blockShift=" + blockShift +
", numValues=" + numValues + ", MAX_ARRAY_LENGTH=" + ArrayUtil.MAX_ARRAY_LENGTH);
}
this.meta = metaOut;
this.data = dataOut;
this.numValues = numValues;
if (blockShift < 2 || blockShift > 30) {
throw new IllegalArgumentException("blockShift must be in [3-30], got " + blockShift);
}
final int blockSize = 1 << blockShift;
this.buffer = new long[blockSize];
this.bufferSize = 0;

View File

@ -26,12 +26,28 @@ import org.apache.lucene.store.Directory;
import org.apache.lucene.store.IOContext;
import org.apache.lucene.store.IndexInput;
import org.apache.lucene.store.IndexOutput;
import org.apache.lucene.util.ArrayUtil;
import org.apache.lucene.util.LongValues;
import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.util.TestUtil;
public class TestDirectMonotonic extends LuceneTestCase {
public void testValidation() {
IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
() -> DirectMonotonicWriter.getInstance(null, null, -1, 10));
assertEquals("numValues can't be negative, got -1", e.getMessage());
e = expectThrows(IllegalArgumentException.class,
() -> DirectMonotonicWriter.getInstance(null, null, 10, 1));
assertEquals("blockShift must be in [2-22], got 1", e.getMessage());
e = expectThrows(IllegalArgumentException.class,
() -> DirectMonotonicWriter.getInstance(null, null, 1L << 40, 5));
assertEquals("blockShift is too low for the provided number of values: blockShift=5, numValues=1099511627776, MAX_ARRAY_LENGTH=" +
ArrayUtil.MAX_ARRAY_LENGTH, e.getMessage());
}
public void testEmpty() throws IOException {
Directory dir = newDirectory();
final int blockShift = TestUtil.nextInt(random(), DirectMonotonicWriter.MIN_BLOCK_SHIFT, DirectMonotonicWriter.MAX_BLOCK_SHIFT);