8318915: Enhance checks in BigDecimal.toPlainString()
Reviewed-by: rriggs, bpb
This commit is contained in:
parent
7d25f1c6cb
commit
a6785e4d63
@ -3503,21 +3503,19 @@ public class BigDecimal extends Number implements Comparable<BigDecimal> {
|
|||||||
return "0";
|
return "0";
|
||||||
}
|
}
|
||||||
int trailingZeros = checkScaleNonZero((-(long)scale));
|
int trailingZeros = checkScaleNonZero((-(long)scale));
|
||||||
StringBuilder buf;
|
String str = intCompact != INFLATED
|
||||||
if(intCompact!=INFLATED) {
|
? Long.toString(intCompact)
|
||||||
buf = new StringBuilder(20+trailingZeros);
|
: intVal.toString();
|
||||||
buf.append(intCompact);
|
int len = str.length() + trailingZeros;
|
||||||
} else {
|
if (len < 0) {
|
||||||
String str = intVal.toString();
|
throw new OutOfMemoryError("too large to fit in a String");
|
||||||
buf = new StringBuilder(str.length()+trailingZeros);
|
|
||||||
buf.append(str);
|
|
||||||
}
|
|
||||||
for (int i = 0; i < trailingZeros; i++) {
|
|
||||||
buf.append('0');
|
|
||||||
}
|
}
|
||||||
|
StringBuilder buf = new StringBuilder(len);
|
||||||
|
buf.append(str);
|
||||||
|
buf.repeat('0', trailingZeros);
|
||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
String str ;
|
String str;
|
||||||
if(intCompact!=INFLATED) {
|
if(intCompact!=INFLATED) {
|
||||||
str = Long.toString(Math.abs(intCompact));
|
str = Long.toString(Math.abs(intCompact));
|
||||||
} else {
|
} else {
|
||||||
@ -3527,11 +3525,11 @@ public class BigDecimal extends Number implements Comparable<BigDecimal> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Returns a digit.digit string */
|
/* Returns a digit.digit string */
|
||||||
private String getValueString(int signum, String intString, int scale) {
|
private static String getValueString(int signum, String intString, int scale) {
|
||||||
/* Insert decimal point */
|
/* Insert decimal point */
|
||||||
StringBuilder buf;
|
StringBuilder buf;
|
||||||
int insertionPoint = intString.length() - scale;
|
int insertionPoint = intString.length() - scale;
|
||||||
if (insertionPoint == 0) { /* Point goes right before intVal */
|
if (insertionPoint == 0) { /* Point goes just before intVal */
|
||||||
return (signum<0 ? "-0." : "0.") + intString;
|
return (signum<0 ? "-0." : "0.") + intString;
|
||||||
} else if (insertionPoint > 0) { /* Point goes inside intVal */
|
} else if (insertionPoint > 0) { /* Point goes inside intVal */
|
||||||
buf = new StringBuilder(intString);
|
buf = new StringBuilder(intString);
|
||||||
@ -3539,11 +3537,13 @@ public class BigDecimal extends Number implements Comparable<BigDecimal> {
|
|||||||
if (signum < 0)
|
if (signum < 0)
|
||||||
buf.insert(0, '-');
|
buf.insert(0, '-');
|
||||||
} else { /* We must insert zeros between point and intVal */
|
} else { /* We must insert zeros between point and intVal */
|
||||||
buf = new StringBuilder(3-insertionPoint + intString.length());
|
int len = (signum < 0 ? 3 : 2) + scale;
|
||||||
buf.append(signum<0 ? "-0." : "0.");
|
if (len < 0) {
|
||||||
for (int i=0; i<-insertionPoint; i++) {
|
throw new OutOfMemoryError("too large to fit in a String");
|
||||||
buf.append('0');
|
|
||||||
}
|
}
|
||||||
|
buf = new StringBuilder(len);
|
||||||
|
buf.append(signum<0 ? "-0." : "0.");
|
||||||
|
buf.repeat('0', -insertionPoint); // insertionPoint != MIN_VALUE
|
||||||
buf.append(intString);
|
buf.append(intString);
|
||||||
}
|
}
|
||||||
return buf.toString();
|
return buf.toString();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* @test
|
* @test
|
||||||
* @bug 4984872
|
* @bug 4984872 8318915
|
||||||
* @summary Basic tests of toPlainString method
|
* @summary Basic tests of toPlainString method
|
||||||
* @run main ToPlainStringTests
|
* @run main ToPlainStringTests
|
||||||
* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+EliminateAutoBox -XX:AutoBoxCacheMax=20000 ToPlainStringTests
|
* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+EliminateAutoBox -XX:AutoBoxCacheMax=20000 ToPlainStringTests
|
||||||
@ -67,6 +67,11 @@ public class ToPlainStringTests {
|
|||||||
{"12345678901234567890", "12345678901234567890"},
|
{"12345678901234567890", "12345678901234567890"},
|
||||||
{"12345678901234567890e22", "123456789012345678900000000000000000000000"},
|
{"12345678901234567890e22", "123456789012345678900000000000000000000000"},
|
||||||
{"12345678901234567890e-22", "0.0012345678901234567890"},
|
{"12345678901234567890e-22", "0.0012345678901234567890"},
|
||||||
|
|
||||||
|
{"12345e-1", "1234.5"},
|
||||||
|
{"12345e-2", "123.45"},
|
||||||
|
{"12345e-3", "12.345"},
|
||||||
|
{"12345e-4", "1.2345"},
|
||||||
};
|
};
|
||||||
|
|
||||||
int errors = 0;
|
int errors = 0;
|
||||||
@ -89,6 +94,38 @@ public class ToPlainStringTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String[] failingCases = {
|
||||||
|
"1E-" + (Integer.MAX_VALUE - 0), // MAX_VALUE + 2 chars
|
||||||
|
"1E-" + (Integer.MAX_VALUE - 1), // MAX_VALUE + 1 chars
|
||||||
|
|
||||||
|
"-1E-" + (Integer.MAX_VALUE - 0), // MAX_VALUE + 3 chars
|
||||||
|
"-1E-" + (Integer.MAX_VALUE - 1), // MAX_VALUE + 2 chars
|
||||||
|
"-1E-" + (Integer.MAX_VALUE - 2), // MAX_VALUE + 1 chars
|
||||||
|
|
||||||
|
"123456789E-" + (Integer.MAX_VALUE - 0), // MAX_VALUE + 2 chars
|
||||||
|
"123456789E-" + (Integer.MAX_VALUE - 1), // MAX_VALUE + 1 chars
|
||||||
|
|
||||||
|
"-123456789E-" + (Integer.MAX_VALUE - 0), // MAX_VALUE + 3 chars
|
||||||
|
"-123456789E-" + (Integer.MAX_VALUE - 1), // MAX_VALUE + 2 chars
|
||||||
|
"-123456789E-" + (Integer.MAX_VALUE - 2), // MAX_VALUE + 1 chars
|
||||||
|
|
||||||
|
"1E" + Integer.MAX_VALUE, // MAX_VALUE + 1 chars
|
||||||
|
"123456789E" + Integer.MAX_VALUE, // MAX_VALUE + 9 chars
|
||||||
|
|
||||||
|
"-1E" + Integer.MAX_VALUE, // MAX_VALUE + 2 chars
|
||||||
|
"-123456789E" + Integer.MAX_VALUE, // MAX_VALUE + 10 chars
|
||||||
|
};
|
||||||
|
/* We expect pre-emptive OutOfMemoryErrors, nothing else */
|
||||||
|
for (String failingCase : failingCases) {
|
||||||
|
try {
|
||||||
|
new BigDecimal(failingCase).toPlainString();
|
||||||
|
} catch (OutOfMemoryError expected) {
|
||||||
|
continue;
|
||||||
|
} catch (Throwable ignored) {
|
||||||
|
}
|
||||||
|
++errors;
|
||||||
|
}
|
||||||
|
|
||||||
if(errors > 0)
|
if(errors > 0)
|
||||||
throw new RuntimeException(errors + " errors during run.");
|
throw new RuntimeException(errors + " errors during run.");
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user