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
pull/4760/head
Ruben Dijkstra 9 years ago committed by Phillip Webb
parent 58fd403bd0
commit 3bd4771130

@ -110,11 +110,11 @@ public class RandomValuePropertySource extends PropertySource<Random> {
private long getNextLongInRange(String range) { private long getNextLongInRange(String range) {
String[] tokens = StringUtils.commaDelimitedListToStringArray(range); String[] tokens = StringUtils.commaDelimitedListToStringArray(range);
if (tokens.length == 1) { 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 lowerBound = Long.parseLong(tokens[0]);
long upperBound = Long.parseLong(tokens[1]) - lowerBound; long upperBound = Long.parseLong(tokens[1]) - lowerBound;
return lowerBound + Math.abs(getSource().nextLong()) % upperBound; return lowerBound + Math.abs(getSource().nextLong() % upperBound);
} }
private Object getRandomBytes() { private Object getRandomBytes() {

@ -16,7 +16,10 @@
package org.springframework.boot.context.config; package org.springframework.boot.context.config;
import java.util.Random;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mockito;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
@ -83,4 +86,27 @@ public class RandomValuePropertySourceTests {
assertNotNull(value); assertNotNull(value);
assertTrue(value < 10L); 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);
}
} }

Loading…
Cancel
Save