changeset 11001:492f4fb4a130

8074032: Instant.ofEpochMilli(millis).toEpochMilli() can throw arithmetic overflow in toEpochMilli() Summary: Instant.toEpochMilli() now takes into account the sign of the 'seconds' field. Reviewed-by: rriggs, scolebourne
author igerasim
date Sat, 08 Aug 2015 03:23:52 +0300
parents 277b0f9f4632
children 2fdb5825ea0a
files src/share/classes/java/time/Instant.java test/java/time/test/java/time/TestInstant.java
diffstat 2 files changed, 31 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/java/time/Instant.java	Thu Aug 06 12:18:41 2015 -0700
+++ b/src/share/classes/java/time/Instant.java	Sat Aug 08 03:23:52 2015 +0300
@@ -1229,8 +1229,14 @@
      * @throws ArithmeticException if numeric overflow occurs
      */
     public long toEpochMilli() {
-        long millis = Math.multiplyExact(seconds, 1000);
-        return millis + nanos / 1000_000;
+        if (seconds < 0 && nanos > 0) {
+            long millis = Math.multiplyExact(seconds+1, 1000);
+            long adjustment = nanos / 1000_000 - 1000;
+            return millis + adjustment;
+        } else {
+            long millis = Math.multiplyExact(seconds, 1000);
+            return millis + nanos / 1000_000;
+        }
     }
 
     //-----------------------------------------------------------------------
--- a/test/java/time/test/java/time/TestInstant.java	Thu Aug 06 12:18:41 2015 -0700
+++ b/test/java/time/test/java/time/TestInstant.java	Sat Aug 08 03:23:52 2015 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -62,6 +62,8 @@
 import java.time.Instant;
 
 import org.testng.annotations.Test;
+import org.testng.annotations.DataProvider;
+import static org.testng.Assert.assertEquals;
 
 /**
  * Test Instant.
@@ -74,4 +76,24 @@
         assertImmutable(Instant.class);
     }
 
+    @DataProvider(name="sampleEpochMillis")
+    private Object[][] provider_sampleEpochMillis() {
+        return new Object[][] {
+            {"Long.MAX_VALUE", Long.MAX_VALUE},
+            {"Long.MAX_VALUE-1", Long.MAX_VALUE - 1},
+            {"1", 1L},
+            {"0", 0L},
+            {"-1", -1L},
+            {"Long.MIN_VALUE+1", Long.MIN_VALUE + 1},
+            {"Long.MIN_VALUE", Long.MIN_VALUE}
+        };
+    }
+
+    @Test(dataProvider="sampleEpochMillis")
+    public void test_epochMillis(String name, long millis) {
+        Instant t1 = Instant.ofEpochMilli(millis);
+        long m = t1.toEpochMilli();
+        assertEquals(millis, m, name);
+    }
+
 }