LUCENE-4568: Fix integer overflow in PagedBytes.PagedBytesData{In,Out}put.getPosition.

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1412099 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Adrien Grand 2012-11-21 13:53:56 +00:00
parent 6f5c10b305
commit 24b4d21720
3 changed files with 40 additions and 6 deletions

View File

@ -154,6 +154,9 @@ Bug Fixes
WFST suggesters when no suggestions were added (selckin via Mike
McCandless)
* LUCENE-4568: Fixed integer overflow in
PagedBytes.PagedBytesData{In,Out}put.getPosition. (Adrien Grand)
Optimizations
* LUCENE-2221: oal.util.BitUtil was modified to use Long.bitCount and

View File

@ -256,6 +256,7 @@ public final class PagedBytes {
/** 1<<blockBits must be bigger than biggest single
* BytesRef slice that will be pulled */
public PagedBytes(int blockBits) {
assert blockBits > 0 && blockBits <= 31 : blockBits;
this.blockSize = 1 << blockBits;
this.blockBits = blockBits;
blockMask = blockSize-1;
@ -423,7 +424,7 @@ public final class PagedBytes {
/** Returns the current byte position. */
public long getPosition() {
return currentBlockIndex * blockSize + currentBlockUpto;
return (long) currentBlockIndex * blockSize + currentBlockUpto;
}
/** Seek to a position previously obtained from
@ -525,11 +526,7 @@ public final class PagedBytes {
/** Return the current byte position. */
public long getPosition() {
if (currentBlock == null) {
return 0;
} else {
return blocks.size() * blockSize + upto;
}
return getPointer();
}
}

View File

@ -17,10 +17,14 @@
package org.apache.lucene.util;
import java.io.IOException;
import java.util.*;
import org.apache.lucene.store.DataInput;
import org.apache.lucene.store.DataOutput;
import org.apache.lucene.util.PagedBytes.PagedBytesDataInput;
import org.apache.lucene.util.PagedBytes.PagedBytesDataOutput;
import org.junit.Ignore;
public class TestPagedBytes extends LuceneTestCase {
@ -131,4 +135,34 @@ public class TestPagedBytes extends LuceneTestCase {
assertEquals(bytes2[i], answer.bytes[answer.offset + i]);
}
}
@Ignore // memory hole
public void testOverflow() throws IOException {
final int blockBits = _TestUtil.nextInt(random(), 14, 28);
final int blockSize = 1 << blockBits;
byte[] arr = new byte[_TestUtil.nextInt(random(), blockSize / 2, blockSize * 2)];
for (int i = 0; i < arr.length; ++i) {
arr[i] = (byte) i;
}
final long numBytes = (1L << 31) + _TestUtil.nextInt(random(), 1, blockSize * 3);
final PagedBytes p = new PagedBytes(blockBits);
final PagedBytesDataOutput out = p.getDataOutput();
for (long i = 0; i < numBytes; ) {
assertEquals(i, out.getPosition());
final int len = (int) Math.min(arr.length, numBytes - i);
out.writeBytes(arr, len);
i += len;
}
assertEquals(numBytes, out.getPosition());
p.freeze(random().nextBoolean());
final PagedBytesDataInput in = p.getDataInput();
for (long offset : new long[] {0L, Integer.MAX_VALUE, numBytes - 1,
_TestUtil.nextLong(random(), 1, numBytes - 2)}) {
in.setPosition(offset);
assertEquals(offset, in.getPosition());
assertEquals(arr[(int) (offset % arr.length)], in.readByte());
assertEquals(offset+1, in.getPosition());
}
}
}