From 3bd4771130631533775707d12e5bdd01ecf0a869 Mon Sep 17 00:00:00 2001 From: Ruben Dijkstra Date: Thu, 3 Dec 2015 14:25:26 +0100 Subject: [PATCH] Protect against Math.abs() with Long.MIN_VALUE Update RandomValuePropertySource to protect against the random source returning Long.MIN_VALUE. In such cases the sign bit can't be unset and prior to this commit the random value stayed negative. Closes gh-4672 --- .../config/RandomValuePropertySource.java | 4 +-- .../RandomValuePropertySourceTests.java | 26 +++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/spring-boot/src/main/java/org/springframework/boot/context/config/RandomValuePropertySource.java b/spring-boot/src/main/java/org/springframework/boot/context/config/RandomValuePropertySource.java index 2b6662b29f..f49c935f11 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/config/RandomValuePropertySource.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/config/RandomValuePropertySource.java @@ -110,11 +110,11 @@ public class RandomValuePropertySource extends PropertySource { private long getNextLongInRange(String range) { String[] tokens = StringUtils.commaDelimitedListToStringArray(range); if (tokens.length == 1) { - return Math.abs(getSource().nextLong()) % Long.parseLong(tokens[0]); + return Math.abs(getSource().nextLong() % Long.parseLong(tokens[0])); } long lowerBound = Long.parseLong(tokens[0]); long upperBound = Long.parseLong(tokens[1]) - lowerBound; - return lowerBound + Math.abs(getSource().nextLong()) % upperBound; + return lowerBound + Math.abs(getSource().nextLong() % upperBound); } private Object getRandomBytes() { diff --git a/spring-boot/src/test/java/org/springframework/boot/context/config/RandomValuePropertySourceTests.java b/spring-boot/src/test/java/org/springframework/boot/context/config/RandomValuePropertySourceTests.java index 98dbc9fd12..953add83b6 100644 --- a/spring-boot/src/test/java/org/springframework/boot/context/config/RandomValuePropertySourceTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/context/config/RandomValuePropertySourceTests.java @@ -16,7 +16,10 @@ package org.springframework.boot.context.config; +import java.util.Random; + import org.junit.Test; +import org.mockito.Mockito; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; @@ -83,4 +86,27 @@ public class RandomValuePropertySourceTests { assertNotNull(value); assertTrue(value < 10L); } + + @Test + public void longOverflow() { + RandomValuePropertySource source = Mockito.spy(this.source); + Mockito.when(source.getSource()).thenReturn(new Random() { + + @Override + public long nextLong() { + // constant that used to become -8, now becomes 8 + return Long.MIN_VALUE; + } + + }); + Long value = (Long) source.getProperty("random.long(10)"); + assertNotNull(value); + assertTrue(value + " is less than 0", value >= 0L); + assertTrue(value + " is more than 10", value < 10L); + + value = (Long) source.getProperty("random.long[4,10]"); + assertNotNull(value); + assertTrue(value + " is less than 4", value >= 4L); + assertTrue(value + " is more than 10", value < 10L); + } }