Skip to content

Commit

Permalink
8299677: Formatter.format might take a long time to format an integer…
Browse files Browse the repository at this point in the history
… or floating-point

Reviewed-by: shade, phh, andrew
Backport-of: 33412c102ce799ff2de3512df77e6e07d76acd36
  • Loading branch information
chadrako authored and Paul Hohensee committed Jul 8, 2024
1 parent c8eb027 commit ddce2b5
Show file tree
Hide file tree
Showing 2 changed files with 322 additions and 4 deletions.
10 changes: 6 additions & 4 deletions jdk/src/share/classes/java/util/Formatter.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 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
Expand Down Expand Up @@ -4380,9 +4380,11 @@ private char getZero(Locale l) {

// apply zero padding
len = sb.length();
if (width != -1 && f.contains(Flags.ZERO_PAD))
for (int k = 0; k < width - len; k++)
sb.insert(begin, zero);
if (width > len && f.contains(Flags.ZERO_PAD)) {
char[] zeros = new char[width - len];
Arrays.fill(zeros, zero);
sb.insert(begin, zeros);
}

return sb;
}
Expand Down
316 changes: 316 additions & 0 deletions jdk/test/java/util/Formatter/Padding.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,316 @@
/*
* Copyright (c) 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

/*
* @test
* @bug 4906370
* @summary Tests to excercise padding on int and double values,
* with various flag combinations.
*/

public class Padding {

private static class Argument {
final String expected;
final String format;
final Object value;

Argument(String expected, String format, Object value) {
this.expected = expected;
this.format = format;
this.value = value;
}
}

static Argument[] arguments = {
/* blank padding, right adjusted, optional plus sign */
new Argument("12", "%1d", 12),
new Argument("12", "%2d", 12),
new Argument(" 12", "%3d", 12),
new Argument(" 12", "%4d", 12),
new Argument(" 12", "%5d", 12),
new Argument(" 12", "%10d", 12),

new Argument("-12", "%1d", -12),
new Argument("-12", "%2d", -12),
new Argument("-12", "%3d", -12),
new Argument(" -12", "%4d", -12),
new Argument(" -12", "%5d", -12),
new Argument(" -12", "%10d", -12),

new Argument("1.2", "%1.1f", 1.2),
new Argument("1.2", "%2.1f", 1.2),
new Argument("1.2", "%3.1f", 1.2),
new Argument(" 1.2", "%4.1f", 1.2),
new Argument(" 1.2", "%5.1f", 1.2),
new Argument(" 1.2", "%10.1f", 1.2),

new Argument("-1.2", "%1.1f", -1.2),
new Argument("-1.2", "%2.1f", -1.2),
new Argument("-1.2", "%3.1f", -1.2),
new Argument("-1.2", "%4.1f", -1.2),
new Argument(" -1.2", "%5.1f", -1.2),
new Argument(" -1.2", "%10.1f", -1.2),

/* blank padding, right adjusted, mandatory plus sign */
new Argument("+12", "%+1d", 12),
new Argument("+12", "%+2d", 12),
new Argument("+12", "%+3d", 12),
new Argument(" +12", "%+4d", 12),
new Argument(" +12", "%+5d", 12),
new Argument(" +12", "%+10d", 12),

new Argument("-12", "%+1d", -12),
new Argument("-12", "%+2d", -12),
new Argument("-12", "%+3d", -12),
new Argument(" -12", "%+4d", -12),
new Argument(" -12", "%+5d", -12),
new Argument(" -12", "%+10d", -12),

new Argument("+1.2", "%+1.1f", 1.2),
new Argument("+1.2", "%+2.1f", 1.2),
new Argument("+1.2", "%+3.1f", 1.2),
new Argument("+1.2", "%+4.1f", 1.2),
new Argument(" +1.2", "%+5.1f", 1.2),
new Argument(" +1.2", "%+10.1f", 1.2),

new Argument("-1.2", "%+1.1f", -1.2),
new Argument("-1.2", "%+2.1f", -1.2),
new Argument("-1.2", "%+3.1f", -1.2),
new Argument("-1.2", "%+4.1f", -1.2),
new Argument(" -1.2", "%+5.1f", -1.2),
new Argument(" -1.2", "%+10.1f", -1.2),

/* blank padding, right adjusted, mandatory blank sign */
new Argument(" 12", "% 1d", 12),
new Argument(" 12", "% 2d", 12),
new Argument(" 12", "% 3d", 12),
new Argument(" 12", "% 4d", 12),
new Argument(" 12", "% 5d", 12),
new Argument(" 12", "% 10d", 12),

new Argument("-12", "% 1d", -12),
new Argument("-12", "% 2d", -12),
new Argument("-12", "% 3d", -12),
new Argument(" -12", "% 4d", -12),
new Argument(" -12", "% 5d", -12),
new Argument(" -12", "% 10d", -12),

new Argument(" 1.2", "% 1.1f", 1.2),
new Argument(" 1.2", "% 2.1f", 1.2),
new Argument(" 1.2", "% 3.1f", 1.2),
new Argument(" 1.2", "% 4.1f", 1.2),
new Argument(" 1.2", "% 5.1f", 1.2),
new Argument(" 1.2", "% 10.1f", 1.2),

new Argument("-1.2", "% 1.1f", -1.2),
new Argument("-1.2", "% 2.1f", -1.2),
new Argument("-1.2", "% 3.1f", -1.2),
new Argument("-1.2", "% 4.1f", -1.2),
new Argument(" -1.2", "% 5.1f", -1.2),
new Argument(" -1.2", "% 10.1f", -1.2),

/* blank padding, left adjusted, optional sign */
new Argument("12", "%-1d", 12),
new Argument("12", "%-2d", 12),
new Argument("12 ", "%-3d", 12),
new Argument("12 ", "%-4d", 12),
new Argument("12 ", "%-5d", 12),
new Argument("12 ", "%-10d", 12),

new Argument("-12", "%-1d", -12),
new Argument("-12", "%-2d", -12),
new Argument("-12", "%-3d", -12),
new Argument("-12 ", "%-4d", -12),
new Argument("-12 ", "%-5d", -12),
new Argument("-12 ", "%-10d", -12),

new Argument("1.2", "%-1.1f", 1.2),
new Argument("1.2", "%-2.1f", 1.2),
new Argument("1.2", "%-3.1f", 1.2),
new Argument("1.2 ", "%-4.1f", 1.2),
new Argument("1.2 ", "%-5.1f", 1.2),
new Argument("1.2 ", "%-10.1f", 1.2),

new Argument("-1.2", "%-1.1f", -1.2),
new Argument("-1.2", "%-2.1f", -1.2),
new Argument("-1.2", "%-3.1f", -1.2),
new Argument("-1.2", "%-4.1f", -1.2),
new Argument("-1.2 ", "%-5.1f", -1.2),
new Argument("-1.2 ", "%-10.1f", -1.2),

/* blank padding, left adjusted, mandatory plus sign */
new Argument("+12", "%-+1d", 12),
new Argument("+12", "%-+2d", 12),
new Argument("+12", "%-+3d", 12),
new Argument("+12 ", "%-+4d", 12),
new Argument("+12 ", "%-+5d", 12),
new Argument("+12 ", "%-+10d", 12),

new Argument("-12", "%-+1d", -12),
new Argument("-12", "%-+2d", -12),
new Argument("-12", "%-+3d", -12),
new Argument("-12 ", "%-+4d", -12),
new Argument("-12 ", "%-+5d", -12),
new Argument("-12 ", "%-+10d", -12),

new Argument("+1.2", "%-+1.1f", 1.2),
new Argument("+1.2", "%-+2.1f", 1.2),
new Argument("+1.2", "%-+3.1f", 1.2),
new Argument("+1.2", "%-+4.1f", 1.2),
new Argument("+1.2 ", "%-+5.1f", 1.2),
new Argument("+1.2 ", "%-+10.1f", 1.2),

new Argument("-1.2", "%-+1.1f", -1.2),
new Argument("-1.2", "%-+2.1f", -1.2),
new Argument("-1.2", "%-+3.1f", -1.2),
new Argument("-1.2", "%-+4.1f", -1.2),
new Argument("-1.2 ", "%-+5.1f", -1.2),
new Argument("-1.2 ", "%-+10.1f", -1.2),

/* blank padding, left adjusted, mandatory blank sign */
new Argument(" 12", "%- 1d", 12),
new Argument(" 12", "%- 2d", 12),
new Argument(" 12", "%- 3d", 12),
new Argument(" 12 ", "%- 4d", 12),
new Argument(" 12 ", "%- 5d", 12),
new Argument(" 12 ", "%- 10d", 12),

new Argument("-12", "%- 1d", -12),
new Argument("-12", "%- 2d", -12),
new Argument("-12", "%- 3d", -12),
new Argument("-12 ", "%- 4d", -12),
new Argument("-12 ", "%- 5d", -12),
new Argument("-12 ", "%- 10d", -12),

new Argument(" 1.2", "%- 1.1f", 1.2),
new Argument(" 1.2", "%- 2.1f", 1.2),
new Argument(" 1.2", "%- 3.1f", 1.2),
new Argument(" 1.2", "%- 4.1f", 1.2),
new Argument(" 1.2 ", "%- 5.1f", 1.2),
new Argument(" 1.2 ", "%- 10.1f", 1.2),

new Argument("-1.2", "%- 1.1f", -1.2),
new Argument("-1.2", "%- 2.1f", -1.2),
new Argument("-1.2", "%- 3.1f", -1.2),
new Argument("-1.2", "%- 4.1f", -1.2),
new Argument("-1.2 ", "%- 5.1f", -1.2),
new Argument("-1.2 ", "%- 10.1f", -1.2),

/* zero padding, right adjusted, optional sign */
new Argument("12", "%01d", 12),
new Argument("12", "%02d", 12),
new Argument("012", "%03d", 12),
new Argument("0012", "%04d", 12),
new Argument("00012", "%05d", 12),
new Argument("0000000012", "%010d", 12),

new Argument("-12", "%01d", -12),
new Argument("-12", "%02d", -12),
new Argument("-12", "%03d", -12),
new Argument("-012", "%04d", -12),
new Argument("-0012", "%05d", -12),
new Argument("-000000012", "%010d", -12),

new Argument("1.2", "%01.1f", 1.2),
new Argument("1.2", "%02.1f", 1.2),
new Argument("1.2", "%03.1f", 1.2),
new Argument("01.2", "%04.1f", 1.2),
new Argument("001.2", "%05.1f", 1.2),
new Argument("00000001.2", "%010.1f", 1.2),

new Argument("-1.2", "%01.1f", -1.2),
new Argument("-1.2", "%02.1f", -1.2),
new Argument("-1.2", "%03.1f", -1.2),
new Argument("-1.2", "%04.1f", -1.2),
new Argument("-01.2", "%05.1f", -1.2),
new Argument("-0000001.2", "%010.1f", -1.2),

/* zero padding, right adjusted, mandatory plus sign */
new Argument("+12", "%+01d", 12),
new Argument("+12", "%+02d", 12),
new Argument("+12", "%+03d", 12),
new Argument("+012", "%+04d", 12),
new Argument("+0012", "%+05d", 12),
new Argument("+000000012", "%+010d", 12),

new Argument("-12", "%+01d", -12),
new Argument("-12", "%+02d", -12),
new Argument("-12", "%+03d", -12),
new Argument("-012", "%+04d", -12),
new Argument("-0012", "%+05d", -12),
new Argument("-000000012", "%+010d", -12),

new Argument("+1.2", "%+01.1f", 1.2),
new Argument("+1.2", "%+02.1f", 1.2),
new Argument("+1.2", "%+03.1f", 1.2),
new Argument("+1.2", "%+04.1f", 1.2),
new Argument("+01.2", "%+05.1f", 1.2),
new Argument("+0000001.2", "%+010.1f", 1.2),

new Argument("-1.2", "%+01.1f", -1.2),
new Argument("-1.2", "%+02.1f", -1.2),
new Argument("-1.2", "%+03.1f", -1.2),
new Argument("-1.2", "%+04.1f", -1.2),
new Argument("-01.2", "%+05.1f", -1.2),
new Argument("-0000001.2", "%+010.1f", -1.2),

/* zero padding, right adjusted, mandatory blank sign */
new Argument(" 12", "% 01d", 12),
new Argument(" 12", "% 02d", 12),
new Argument(" 12", "% 03d", 12),
new Argument(" 012", "% 04d", 12),
new Argument(" 0012", "% 05d", 12),
new Argument(" 000000012", "% 010d", 12),

new Argument("-12", "% 01d", -12),
new Argument("-12", "% 02d", -12),
new Argument("-12", "% 03d", -12),
new Argument("-012", "% 04d", -12),
new Argument("-0012", "% 05d", -12),
new Argument("-000000012", "% 010d", -12),

new Argument(" 1.2", "% 01.1f", 1.2),
new Argument(" 1.2", "% 02.1f", 1.2),
new Argument(" 1.2", "% 03.1f", 1.2),
new Argument(" 1.2", "% 04.1f", 1.2),
new Argument(" 01.2", "% 05.1f", 1.2),
new Argument(" 0000001.2", "% 010.1f", 1.2),

new Argument("-1.2", "% 01.1f", -1.2),
new Argument("-1.2", "% 02.1f", -1.2),
new Argument("-1.2", "% 03.1f", -1.2),
new Argument("-1.2", "% 04.1f", -1.2),
new Argument("-01.2", "% 05.1f", -1.2),
new Argument("-0000001.2", "% 010.1f", -1.2),
};

public static void main(String [] args) {
for (Argument arg : arguments) {
if (!arg.expected.equals(String.format(arg.format, arg.value))) {
throw new RuntimeException("Expected value " + arg.expected +
" not returned from String.format(" + arg.format + ", " + arg.value + ")");
}
}
}
}

1 comment on commit ddce2b5

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.