HBASE-10718 TestHLogSplit fails when it sets a KV size to be negative (Esteban Gutierrez)

git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1576747 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andrew Kyle Purtell 2014-03-12 14:16:24 +00:00
parent be21fcd1d6
commit b22548ff06
2 changed files with 50 additions and 2 deletions

View File

@ -2759,7 +2759,12 @@ public class KeyValue implements Cell, HeapSize, Cloneable {
* @throws IOException * @throws IOException
*/ */
public static KeyValue create(int length, final DataInput in) throws IOException { public static KeyValue create(int length, final DataInput in) throws IOException {
if (length == 0) return null;
if (length <= 0) {
if (length == 0) return null;
throw new IOException("Failed read " + length + " bytes, stream corrupt?");
}
// This is how the old Writables.readFrom used to deserialize. Didn't even vint. // This is how the old Writables.readFrom used to deserialize. Didn't even vint.
byte [] bytes = new byte[length]; byte [] bytes = new byte[length];
in.readFully(bytes); in.readFully(bytes);

View File

@ -22,11 +22,13 @@ package org.apache.hadoop.hbase;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.NavigableSet; import java.util.NavigableSet;
@ -75,6 +77,47 @@ public class TestSerialization {
assertEquals(kv.getLength(), deserializedKv.getLength()); assertEquals(kv.getLength(), deserializedKv.getLength());
} }
@Test public void testCreateKeyValueInvalidNegativeLength() {
KeyValue kv_0 = new KeyValue(Bytes.toBytes("myRow"), Bytes.toBytes("myCF"), // 51 bytes
Bytes.toBytes("myQualifier"), 12345L, Bytes.toBytes("my12345"));
KeyValue kv_1 = new KeyValue(Bytes.toBytes("myRow"), Bytes.toBytes("myCF"), // 49 bytes
Bytes.toBytes("myQualifier"), 12345L, Bytes.toBytes("my123"));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
long l = 0;
try {
l = KeyValue.oswrite(kv_0, dos, false);
l += KeyValue.oswrite(kv_1, dos, false);
assertEquals(100L, l);
} catch (IOException e) {
fail("Unexpected IOException" + e.getMessage());
}
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
DataInputStream dis = new DataInputStream(bais);
try {
KeyValue.create(dis);
assertTrue(kv_0.equals(kv_1));
} catch (Exception e) {
fail("Unexpected Exception" + e.getMessage());
}
// length -1
try {
// even if we have a good kv now in dis we will just pass length with -1 for simplicity
KeyValue.create(-1, dis);
fail("Expected corrupt stream");
} catch (Exception e) {
assertEquals("Failed read -1 bytes, stream corrupt?", e.getMessage());
}
}
@Test @Test
public void testSplitLogTask() throws DeserializationException { public void testSplitLogTask() throws DeserializationException {
SplitLogTask slt = new SplitLogTask.Unassigned(ServerName.valueOf("mgr,1,1")); SplitLogTask slt = new SplitLogTask.Unassigned(ServerName.valueOf("mgr,1,1"));