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";
|
||||
}
|
||||
int trailingZeros = checkScaleNonZero((-(long)scale));
|
||||
StringBuilder buf;
|
||||
if(intCompact!=INFLATED) {
|
||||
buf = new StringBuilder(20+trailingZeros);
|
||||
buf.append(intCompact);
|
||||
} else {
|
||||
String str = intVal.toString();
|
||||
buf = new StringBuilder(str.length()+trailingZeros);
|
||||
buf.append(str);
|
||||
}
|
||||
for (int i = 0; i < trailingZeros; i++) {
|
||||
buf.append('0');
|
||||
String str = intCompact != INFLATED
|
||||
? Long.toString(intCompact)
|
||||
: intVal.toString();
|
||||
int len = str.length() + trailingZeros;
|
||||
if (len < 0) {
|
||||
throw new OutOfMemoryError("too large to fit in a String");
|
||||
}
|
||||
StringBuilder buf = new StringBuilder(len);
|
||||
buf.append(str);
|
||||
buf.repeat('0', trailingZeros);
|
||||
return buf.toString();
|
||||
}
|
||||
String str ;
|
||||
String str;
|
||||
if(intCompact!=INFLATED) {
|
||||
str = Long.toString(Math.abs(intCompact));
|
||||
} else {
|
||||
@ -3527,11 +3525,11 @@ public class BigDecimal extends Number implements Comparable<BigDecimal> {
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
StringBuilder buf;
|
||||
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;
|
||||
} else if (insertionPoint > 0) { /* Point goes inside intVal */
|
||||
buf = new StringBuilder(intString);
|
||||
@ -3539,11 +3537,13 @@ public class BigDecimal extends Number implements Comparable<BigDecimal> {
|
||||
if (signum < 0)
|
||||
buf.insert(0, '-');
|
||||
} else { /* We must insert zeros between point and intVal */
|
||||
buf = new StringBuilder(3-insertionPoint + intString.length());
|
||||
buf.append(signum<0 ? "-0." : "0.");
|
||||
for (int i=0; i<-insertionPoint; i++) {
|
||||
buf.append('0');
|
||||
int len = (signum < 0 ? 3 : 2) + scale;
|
||||
if (len < 0) {
|
||||
throw new OutOfMemoryError("too large to fit in a String");
|
||||
}
|
||||
buf = new StringBuilder(len);
|
||||
buf.append(signum<0 ? "-0." : "0.");
|
||||
buf.repeat('0', -insertionPoint); // insertionPoint != MIN_VALUE
|
||||
buf.append(intString);
|
||||
}
|
||||
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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4984872
|
||||
* @bug 4984872 8318915
|
||||
* @summary Basic tests of toPlainString method
|
||||
* @run main ToPlainStringTests
|
||||
* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+EliminateAutoBox -XX:AutoBoxCacheMax=20000 ToPlainStringTests
|
||||
@ -67,6 +67,11 @@ public class ToPlainStringTests {
|
||||
{"12345678901234567890", "12345678901234567890"},
|
||||
{"12345678901234567890e22", "123456789012345678900000000000000000000000"},
|
||||
{"12345678901234567890e-22", "0.0012345678901234567890"},
|
||||
|
||||
{"12345e-1", "1234.5"},
|
||||
{"12345e-2", "123.45"},
|
||||
{"12345e-3", "12.345"},
|
||||
{"12345e-4", "1.2345"},
|
||||
};
|
||||
|
||||
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)
|
||||
throw new RuntimeException(errors + " errors during run.");
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user