From 454206b5926dbe6d6231236597b7004fec814f9d Mon Sep 17 00:00:00 2001 From: Mohammad Arshad Date: Tue, 17 May 2022 10:54:38 +0530 Subject: [PATCH] HBASE-26856:BufferedDataBlockEncoder.OnheapDecodedCell value can get corrupted (#4394) Created OnheapDecodedCell and OffheapDecodedExtendedCell objects with duplicate copy of ByteBuffer's underlying array instead of original ByteBuffer Signed-off-by: Andrew Purtell Signed-off-by: Pankaj Kumar (cherry picked from commit c198f23e5eb078abc47d4c3439477c6c2b4d5136) --- .../io/encoding/BufferedDataBlockEncoder.java | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/io/encoding/BufferedDataBlockEncoder.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/io/encoding/BufferedDataBlockEncoder.java index b155d9b854e..db1206aaea9 100644 --- a/hbase-common/src/main/java/org/apache/hadoop/hbase/io/encoding/BufferedDataBlockEncoder.java +++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/io/encoding/BufferedDataBlockEncoder.java @@ -232,9 +232,10 @@ abstract class BufferedDataBlockEncoder extends AbstractDataBlockEncoder { int tOffset = 0; if (this.includeTags) { if (this.tagCompressionContext == null) { - tagsArray = valAndTagsBuffer.array(); tOffset = valAndTagsBuffer.arrayOffset() + vOffset + this.valueLength + tagsLenSerializationSize; + tagsArray = Bytes.copy(valAndTagsBuffer.array(), tOffset, this.tagsLength); + tOffset = 0; } else { tagsArray = Bytes.copy(tagsBuffer, 0, this.tagsLength); tOffset = 0; @@ -243,9 +244,8 @@ abstract class BufferedDataBlockEncoder extends AbstractDataBlockEncoder { return new OnheapDecodedCell(Bytes.copy(keyBuffer, 0, this.keyLength), currentKey.getRowLength(), currentKey.getFamilyOffset(), currentKey.getFamilyLength(), currentKey.getQualifierOffset(), currentKey.getQualifierLength(), currentKey.getTimestamp(), - currentKey.getTypeByte(), valAndTagsBuffer.array(), - valAndTagsBuffer.arrayOffset() + vOffset, this.valueLength, memstoreTS, tagsArray, tOffset, - this.tagsLength); + currentKey.getTypeByte(), Bytes.copy(valAndTagsBuffer.array(), valAndTagsBuffer.arrayOffset() + vOffset, + this.valueLength), 0, this.valueLength, memstoreTS, tagsArray, tOffset, this.tagsLength); } private Cell toOffheapCell(ByteBuffer valAndTagsBuffer, int vOffset, @@ -254,13 +254,26 @@ abstract class BufferedDataBlockEncoder extends AbstractDataBlockEncoder { int tOffset = 0; if (this.includeTags) { if (this.tagCompressionContext == null) { - tagsBuf = valAndTagsBuffer; tOffset = vOffset + this.valueLength + tagsLenSerializationSize; + byte[] output = new byte[this.tagsLength]; + ByteBufferUtils.copyFromBufferToArray(output, valAndTagsBuffer, tOffset, 0, + this.tagsLength); + tagsBuf = ByteBuffer.wrap(output); + tOffset = 0; } else { tagsBuf = ByteBuffer.wrap(Bytes.copy(tagsBuffer, 0, this.tagsLength)); tOffset = 0; } } + + if (this.valueLength > 0) { + byte[] output = new byte[this.valueLength]; + ByteBufferUtils.copyFromBufferToArray(output, valAndTagsBuffer, vOffset, 0, + this.valueLength); + valAndTagsBuffer = ByteBuffer.wrap(output); + vOffset = 0; + } + return new OffheapDecodedExtendedCell( ByteBuffer.wrap(Bytes.copy(keyBuffer, 0, this.keyLength)), currentKey.getRowLength(), currentKey.getFamilyOffset(), currentKey.getFamilyLength(), currentKey.getQualifierOffset(),