From 961a9c14f63b5c5a06ebd69b39a32aa0b8d0e4fc Mon Sep 17 00:00:00 2001 From: igerasim Date: Sat, 8 Aug 2015 03:23:52 +0300 Subject: [PATCH] 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 --- src/share/classes/java/time/Instant.java | 10 ++++++-- .../java/time/test/java/time/TestInstant.java | 24 ++++++++++++++++++- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/share/classes/java/time/Instant.java b/src/share/classes/java/time/Instant.java index 91a177c9a..a660b1d3f 100644 --- a/src/share/classes/java/time/Instant.java +++ b/src/share/classes/java/time/Instant.java @@ -1229,8 +1229,14 @@ public final class Instant * @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; + } } //----------------------------------------------------------------------- diff --git a/test/java/time/test/java/time/TestInstant.java b/test/java/time/test/java/time/TestInstant.java index cf135a1ae..203bb5798 100644 --- a/test/java/time/test/java/time/TestInstant.java +++ b/test/java/time/test/java/time/TestInstant.java @@ -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 @@ package test.java.time; 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 @@ public class TestInstant extends AbstractTest { 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); + } + } -- GitLab