From 3896d9ed0a87c77330f3f2c998a6fdafe272e2d6 Mon Sep 17 00:00:00 2001 From: tedyu Date: Sun, 25 Sep 2016 06:37:40 -0700 Subject: [PATCH] HBASE-16692 Make ByteBufferUtils#equals safer and correct (binlijin) --- .../hadoop/hbase/util/ByteBufferUtils.java | 9 ++++++ .../hbase/util/TestByteBufferUtils.java | 29 +++++++++++++++++++ 2 files changed, 38 insertions(+) rename {hbase-server => hbase-common}/src/test/java/org/apache/hadoop/hbase/util/TestByteBufferUtils.java (93%) diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/ByteBufferUtils.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/ByteBufferUtils.java index d788c701d96..c491fe12fb5 100644 --- a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/ByteBufferUtils.java +++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/ByteBufferUtils.java @@ -17,6 +17,7 @@ package org.apache.hadoop.hbase.util; import java.io.ByteArrayOutputStream; +import java.io.DataInput; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; @@ -573,6 +574,10 @@ public final class ByteBufferUtils { } public static boolean equals(ByteBuffer buf1, int o1, int l1, ByteBuffer buf2, int o2, int l2) { + if ((l1 == 0) || (l2 == 0)) { + // both 0 length, return true, or else false + return l1 == l2; + } // Since we're often comparing adjacent sorted data, // it's usual to have equal arrays except for the very last byte // so check that first @@ -627,6 +632,10 @@ public final class ByteBufferUtils { } public static boolean equals(ByteBuffer buf1, int o1, int l1, byte[] buf2, int o2, int l2) { + if ((l1 == 0) || (l2 == 0)) { + // both 0 length, return true, or else false + return l1 == l2; + } // Since we're often comparing adjacent sorted data, // it's usual to have equal arrays except for the very last byte // so check that first diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestByteBufferUtils.java b/hbase-common/src/test/java/org/apache/hadoop/hbase/util/TestByteBufferUtils.java similarity index 93% rename from hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestByteBufferUtils.java rename to hbase-common/src/test/java/org/apache/hadoop/hbase/util/TestByteBufferUtils.java index 8ef07d235e7..dfbc015aea7 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestByteBufferUtils.java +++ b/hbase-common/src/test/java/org/apache/hadoop/hbase/util/TestByteBufferUtils.java @@ -34,6 +34,7 @@ import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; +import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.testclassification.MiscTests; import org.apache.hadoop.hbase.testclassification.SmallTests; import org.apache.hadoop.io.WritableUtils; @@ -398,6 +399,34 @@ public class TestByteBufferUtils { assertTrue(result < 0); } + @Test + public void testEquals() { + byte[] a = Bytes.toBytes("http://A"); + ByteBuffer bb = ByteBuffer.wrap(a); + + assertTrue(ByteBufferUtils.equals(HConstants.EMPTY_BYTE_BUFFER, 0, 0, + HConstants.EMPTY_BYTE_BUFFER, 0, 0)); + + assertFalse(ByteBufferUtils.equals(HConstants.EMPTY_BYTE_BUFFER, 0, 0, bb, + 0, a.length)); + + assertFalse(ByteBufferUtils.equals(bb, 0, 0, HConstants.EMPTY_BYTE_BUFFER, + 0, a.length)); + + assertTrue(ByteBufferUtils.equals(bb, 0, a.length, bb, 0, a.length)); + + assertTrue(ByteBufferUtils.equals(HConstants.EMPTY_BYTE_BUFFER, 0, 0, + HConstants.EMPTY_BYTE_ARRAY, 0, 0)); + + assertFalse(ByteBufferUtils.equals(HConstants.EMPTY_BYTE_BUFFER, 0, 0, a, + 0, a.length)); + + assertFalse(ByteBufferUtils.equals(bb, 0, a.length, + HConstants.EMPTY_BYTE_ARRAY, 0, 0)); + + assertTrue(ByteBufferUtils.equals(bb, 0, a.length, a, 0, a.length)); + } + private static void fillBB(ByteBuffer bb, byte b) { for (int i = bb.position(); i < bb.limit(); i++) { bb.put(i, b);