Merge pull request #41 from caskdata/bugfix/overflow_max_writeptr

TEPHRA-76 Prevent overflow of write pointer value
diff --git a/tephra-core/src/main/java/co/cask/tephra/util/TxUtils.java b/tephra-core/src/main/java/co/cask/tephra/util/TxUtils.java
index 46d65b5..0afa4bf 100644
--- a/tephra-core/src/main/java/co/cask/tephra/util/TxUtils.java
+++ b/tephra-core/src/main/java/co/cask/tephra/util/TxUtils.java
@@ -55,7 +55,8 @@
    */
   public static long getMaxVisibleTimestamp(Transaction tx) {
     // NOTE: +1 here because we want read up to writepointer inclusive, but timerange's end is exclusive
-    return tx.getWritePointer() + 1;
+    // however, we also need to guard against overflow in the case write pointer is set to MAX_VALUE
+    return tx.getWritePointer() < Long.MAX_VALUE ? tx.getWritePointer() + 1 : tx.getWritePointer();
   }
 
   /**
diff --git a/tephra-core/src/test/java/co/cask/tephra/util/TxUtilsTest.java b/tephra-core/src/test/java/co/cask/tephra/util/TxUtilsTest.java
new file mode 100644
index 0000000..f8814bb
--- /dev/null
+++ b/tephra-core/src/test/java/co/cask/tephra/util/TxUtilsTest.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright © 2015 Cask Data, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package co.cask.tephra.util;
+
+import co.cask.tephra.Transaction;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Test cases for {@link TxUtils} utility methods.
+ */
+public class TxUtilsTest {
+  @Test
+  public void testMaxVisibleTimestamp() {
+    // make sure we don't overflow with MAX_VALUE write pointer
+    assertEquals(Long.MAX_VALUE, TxUtils.getMaxVisibleTimestamp(Transaction.ALL_VISIBLE_LATEST));
+  }
+}