From d659bde16753d0f498f356ac5d0f2c8493541cd4 Mon Sep 17 00:00:00 2001 From: Nick Dimiduk Date: Mon, 18 Nov 2013 14:33:47 -0800 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. --- .../main/java/org/apache/hadoop/hbase/util/OrderedBytes.java | 3 +++ .../java/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 82f8f81..7e86428 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 1050e88..aef24be 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 @@ -872,9 +872,19 @@ public class TestOrderedBytes { 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() }; -- 1.8.4.2