LUCENE-5218: fix exception when trying to read a 0-byte BinaryDocValues field

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1526538 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael McCandless 2013-09-26 14:59:51 +00:00
parent 8eca0a7ccd
commit d98e92a87c
2 changed files with 43 additions and 3 deletions

View File

@ -86,9 +86,12 @@ public final class PagedBytes {
public void fillSlice(BytesRef b, long start, int length) { public void fillSlice(BytesRef b, long start, int length) {
assert length >= 0: "length=" + length; assert length >= 0: "length=" + length;
assert length <= blockSize+1: "length=" + length; assert length <= blockSize+1: "length=" + length;
b.length = length;
if (length == 0) {
return;
}
final int index = (int) (start >> blockBits); final int index = (int) (start >> blockBits);
final int offset = (int) (start & blockMask); final int offset = (int) (start & blockMask);
b.length = length;
if (blockSize - offset >= length) { if (blockSize - offset >= length) {
// Within block // Within block
b.bytes = blocks[index]; b.bytes = blocks[index];

View File

@ -1432,7 +1432,7 @@ public abstract class BaseDocValuesFormatTestCase extends LuceneTestCase {
public void testBinaryFixedLengthVsStoredFields() throws Exception { public void testBinaryFixedLengthVsStoredFields() throws Exception {
int numIterations = atLeast(1); int numIterations = atLeast(1);
for (int i = 0; i < numIterations; i++) { for (int i = 0; i < numIterations; i++) {
int fixedLength = _TestUtil.nextInt(random(), 1, 10); int fixedLength = _TestUtil.nextInt(random(), 0, 10);
doTestBinaryVsStoredFields(fixedLength, fixedLength); doTestBinaryVsStoredFields(fixedLength, fixedLength);
} }
} }
@ -1440,7 +1440,7 @@ public abstract class BaseDocValuesFormatTestCase extends LuceneTestCase {
public void testBinaryVariableLengthVsStoredFields() throws Exception { public void testBinaryVariableLengthVsStoredFields() throws Exception {
int numIterations = atLeast(1); int numIterations = atLeast(1);
for (int i = 0; i < numIterations; i++) { for (int i = 0; i < numIterations; i++) {
doTestBinaryVsStoredFields(1, 10); doTestBinaryVsStoredFields(0, 10);
} }
} }
@ -2958,6 +2958,43 @@ public abstract class BaseDocValuesFormatTestCase extends LuceneTestCase {
dir.close(); dir.close();
} }
// LUCENE-5218
public void testEmptyBinaryValueOnPageSizes() throws Exception {
// Test larger and larger power-of-two sized values,
// followed by empty string value:
for(int i=0;i<20;i++) {
if (i > 14 && codecAcceptsHugeBinaryValues("field") == false) {
break;
}
Directory dir = newDirectory();
RandomIndexWriter w = new RandomIndexWriter(random(), dir);
BytesRef bytes = new BytesRef();
bytes.bytes = new byte[1<<i];
bytes.length = 1<<i;
for(int j=0;j<4;j++) {
Document doc = new Document();
doc.add(new BinaryDocValuesField("field", bytes));
w.addDocument(doc);
}
Document doc = new Document();
doc.add(new StoredField("id", "5"));
doc.add(new BinaryDocValuesField("field", new BytesRef()));
w.addDocument(doc);
IndexReader r = w.getReader();
w.close();
AtomicReader ar = SlowCompositeReaderWrapper.wrap(r);
BinaryDocValues values = ar.getBinaryDocValues("field");
BytesRef result = new BytesRef();
for(int j=0;j<5;j++) {
values.get(0, result);
assertTrue(result.length == 0 || result.length == 1<<i);
}
ar.close();
dir.close();
}
}
protected boolean codecAcceptsHugeBinaryValues(String field) { protected boolean codecAcceptsHugeBinaryValues(String field) {
return true; return true;
} }