From da89846cf78ff1be7f07bbfee40ebacc23eb9ceb Mon Sep 17 00:00:00 2001 From: ndimiduk Date: Wed, 20 Nov 2013 02:53:51 +0000 Subject: [PATCH] HBASE-9893 Incorrect assert condition in OrderedBytes decoding Correct an invalid assumption in remaining assertion code around OrderedBytes#decodeVarBlob. When an encoded value contains a 1-bit in its LSB position and the length of the encoded byte array is divisible by 7, the value remaining in variable t will be 0x80, resulting in the failed assertion coming out of the decoding loop. This patch preserves the assertion for the general case by resetting 't' at the conclusion of the 7-byte cycle. git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1543699 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/hadoop/hbase/util/OrderedBytes.java | 3 +++ .../org/apache/hadoop/hbase/util/TestOrderedBytes.java | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/OrderedBytes.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/OrderedBytes.java index 82f8f815c99..7e86428d2e6 100644 --- a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/OrderedBytes.java +++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/OrderedBytes.java @@ -1109,6 +1109,9 @@ public class OrderedBytes { if (s == 7) { ret.put((byte) (t | (ord.apply(a[offset + i]) & 0x7f))); i++; + // explicitly reset t -- clean up overflow buffer after decoding + // a full cycle and retain assertion condition below. This happens + t = 0; // when the LSB in the last encoded byte is 1. (HBASE-9893) } else { ret.put((byte) (t | ((ord.apply(a[offset + i]) & 0x7f) >>> s))); } diff --git a/hbase-common/src/test/java/org/apache/hadoop/hbase/util/TestOrderedBytes.java b/hbase-common/src/test/java/org/apache/hadoop/hbase/util/TestOrderedBytes.java index 1050e88135d..aef24be3403 100644 --- a/hbase-common/src/test/java/org/apache/hadoop/hbase/util/TestOrderedBytes.java +++ b/hbase-common/src/test/java/org/apache/hadoop/hbase/util/TestOrderedBytes.java @@ -871,10 +871,20 @@ public class TestOrderedBytes { public void testBlobVar() { byte[][] vals = { "".getBytes(), "foo".getBytes(), "foobarbazbub".getBytes(), + { (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, + (byte) 0xaa, /* 7 bytes of alternating bits; testing around HBASE-9893 */ }, { (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa }, + { (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, + (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, + (byte) 0xaa, (byte) 0xaa, /* 14 bytes of alternating bits; testing around HBASE-9893 */ }, + { (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, + (byte) 0x55, /* 7 bytes of alternating bits; testing around HBASE-9893 */ }, { (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55 }, + { (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, + (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, + (byte) 0x55, (byte) 0x55, /* 14 bytes of alternating bits; testing around HBASE-9893 */ }, "1".getBytes(), "22".getBytes(), "333".getBytes(), "4444".getBytes(), "55555".getBytes(), "666666".getBytes(), "7777777".getBytes(), "88888888".getBytes() };