HBASE-12949 Scanner can be stuck in infinite loop if the HFile is corrupted
Project: http://git-wip-us.apache.org/repos/asf/hbase/repo Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/b6b01a79 Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/b6b01a79 Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/b6b01a79 Branch: refs/heads/hbase-14439 Commit: b6b01a790f600d4699450e2e97349599c9efc0e1 Parents: 5568929 Author: Jerry He <jerry...@apache.org> Authored: Wed Sep 21 13:25:23 2016 -0700 Committer: Jerry He <jerry...@apache.org> Committed: Wed Sep 21 13:25:23 2016 -0700 ---------------------------------------------------------------------- .../hadoop/hbase/io/hfile/HFileReaderImpl.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hbase/blob/b6b01a79/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileReaderImpl.java ---------------------------------------------------------------------- diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileReaderImpl.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileReaderImpl.java index c9e6aea..bd9715b 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileReaderImpl.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileReaderImpl.java @@ -709,8 +709,7 @@ public class HFileReaderImpl implements HFile.Reader, Configurable { long ll = blockBuffer.getLongAfterPosition(offsetFromPos); klen = (int)(ll >> Integer.SIZE); vlen = (int)(Bytes.MASK_FOR_LOWER_INT_IN_LONG ^ ll); - if (klen < 0 || vlen < 0 || klen > blockBuffer.limit() - || vlen > blockBuffer.limit()) { + if (checkKeyLen(klen) || checkLen(vlen)) { throw new IllegalStateException("Invalid klen " + klen + " or vlen " + vlen + ". Block offset: " + curBlock.getOffset() + ", block length: " + blockBuffer.limit() + ", position: " @@ -725,7 +724,7 @@ public class HFileReaderImpl implements HFile.Reader, Configurable { // Read short as unsigned, high byte first tlen = ((blockBuffer.getByteAfterPosition(offsetFromPos) & 0xff) << 8) ^ (blockBuffer.getByteAfterPosition(offsetFromPos + 1) & 0xff); - if (tlen < 0 || tlen > blockBuffer.limit()) { + if (checkLen(tlen)) { throw new IllegalStateException("Invalid tlen " + tlen + ". Block offset: " + curBlock.getOffset() + ", block length: " + blockBuffer.limit() + ", position: " + blockBuffer.position() + " (without header)."); @@ -1141,6 +1140,14 @@ public class HFileReaderImpl implements HFile.Reader, Configurable { /** * @param v + * @return True if v <= 0 or v > current block buffer limit. + */ + protected final boolean checkKeyLen(final int v) { + return v <= 0 || v > this.blockBuffer.limit(); + } + + /** + * @param v * @return True if v < 0 or v > current block buffer limit. */ protected final boolean checkLen(final int v) { @@ -1151,7 +1158,7 @@ public class HFileReaderImpl implements HFile.Reader, Configurable { * Check key and value lengths are wholesome. */ protected final void checkKeyValueLen() { - if (checkLen(this.currKeyLen) || checkLen(this.currValueLen)) { + if (checkKeyLen(this.currKeyLen) || checkLen(this.currValueLen)) { throw new IllegalStateException("Invalid currKeyLen " + this.currKeyLen + " or currValueLen " + this.currValueLen + ". Block offset: " + this.curBlock.getOffset() + ", block length: "