From 9cd7619b5c858130e92806c40747148a89a02940 Mon Sep 17 00:00:00 2001 From: Maytee Chinavanichkit Date: Mon, 2 Oct 2017 15:19:25 +0900 Subject: [PATCH] HBASE-18921 Fix Result.current ArrayIndexOutOfBoundsException Patch ArrayIndexOutOfBoundsException when current() is called after advance() has already returned false Signed-off-by: Chia-Ping Tsai --- .../org/apache/hadoop/hbase/client/Result.java | 16 +++++++++++++--- .../apache/hadoop/hbase/client/TestResult.java | 18 ++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Result.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Result.java index 1871d177321..906caacc608 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Result.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Result.java @@ -30,6 +30,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.NavigableMap; +import java.util.NoSuchElementException; import java.util.TreeMap; import org.apache.hadoop.hbase.Cell; @@ -883,14 +884,23 @@ public class Result implements CellScannable, CellScanner { @Override public Cell current() { - if (cells == null) return null; - return (cellScannerIndex < 0)? null: this.cells[cellScannerIndex]; + if (cells == null + || cellScannerIndex == INITIAL_CELLSCANNER_INDEX + || cellScannerIndex >= cells.length) + return null; + return this.cells[cellScannerIndex]; } @Override public boolean advance() { if (cells == null) return false; - return ++cellScannerIndex < this.cells.length; + cellScannerIndex++; + if (cellScannerIndex < this.cells.length) { + return true; + } else if (cellScannerIndex == this.cells.length) { + return false; + } + throw new NoSuchElementException("Cannot advance beyond the last cell"); } public Boolean getExists() { diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestResult.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestResult.java index 0e93ee011d8..bf9a69a1637 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestResult.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestResult.java @@ -25,6 +25,7 @@ import java.io.IOException; import java.nio.ByteBuffer; import java.util.Arrays; import java.util.List; +import java.util.NoSuchElementException; import junit.framework.TestCase; @@ -106,6 +107,23 @@ public class TestResult extends TestCase { } } + public void testCurrentOnEmptyCell() throws IOException { + Result r = Result.create(new Cell[0]); + assertFalse(r.advance()); + assertNull(r.current()); + } + + public void testAdvanceTwiceOnEmptyCell() throws IOException { + Result r = Result.create(new Cell[0]); + assertFalse(r.advance()); + try { + r.advance(); + fail("NoSuchElementException should have been thrown!"); + } catch (NoSuchElementException ex) { + LOG.debug("As expected: " + ex.getMessage()); + } + } + public void testMultiVersionGetColumn() throws Exception { KeyValue [] kvs1 = genKVs(row, family, value, 1, 100); KeyValue [] kvs2 = genKVs(row, family, value, 200, 100);