8253459: Formatter treats index, width and precision > Integer.MAX_VALUE incorrectly
Reviewed-by: rriggs, smarks
This commit is contained in:
parent
b9db002fef
commit
080c707aab
@ -692,12 +692,28 @@ import sun.util.locale.provider.ResourceBundleBasedAdapter;
|
|||||||
* <p> If the format specifier contains a width or precision with an invalid
|
* <p> If the format specifier contains a width or precision with an invalid
|
||||||
* value or which is otherwise unsupported, then a {@link
|
* value or which is otherwise unsupported, then a {@link
|
||||||
* IllegalFormatWidthException} or {@link IllegalFormatPrecisionException}
|
* IllegalFormatWidthException} or {@link IllegalFormatPrecisionException}
|
||||||
* respectively will be thrown.
|
* respectively will be thrown. Similarly, values of zero for an argument
|
||||||
|
* index will result in an {@link IllegalFormatException}.
|
||||||
*
|
*
|
||||||
* <p> If a format specifier contains a conversion character that is not
|
* <p> If a format specifier contains a conversion character that is not
|
||||||
* applicable to the corresponding argument, then an {@link
|
* applicable to the corresponding argument, then an {@link
|
||||||
* IllegalFormatConversionException} will be thrown.
|
* IllegalFormatConversionException} will be thrown.
|
||||||
*
|
*
|
||||||
|
* <p> Values of <i>precision</i> must be in the range zero to
|
||||||
|
* {@link Integer#MAX_VALUE}, inclusive, otherwise
|
||||||
|
* {@link IllegalFormatPrecisionException} is thrown.</p>
|
||||||
|
*
|
||||||
|
* <p> Values of <i>width</i> must be in the range one to
|
||||||
|
* {@link Integer#MAX_VALUE}, inclusive, otherwise
|
||||||
|
* {@link IllegalFormatWidthException} will be thrown
|
||||||
|
* Note that widths can appear to have a negative value, but the negative sign
|
||||||
|
* is a <i>flag</i>. For example in the format string {@code "%-20s"} the
|
||||||
|
* <i>width</i> is <i>20</i> and the <i>flag</i> is "-".</p>
|
||||||
|
*
|
||||||
|
* <p> Values of <i>index</i> must be in the range one to
|
||||||
|
* {@link Integer#MAX_VALUE}, inclusive, otherwise
|
||||||
|
* {@link IllegalFormatException} will be thrown.</p>
|
||||||
|
*
|
||||||
* <p> All specified exceptions may be thrown by any of the {@code format}
|
* <p> All specified exceptions may be thrown by any of the {@code format}
|
||||||
* methods of {@code Formatter} as well as by any {@code format} convenience
|
* methods of {@code Formatter} as well as by any {@code format} convenience
|
||||||
* methods such as {@link String#format(String,Object...) String.format} and
|
* methods such as {@link String#format(String,Object...) String.format} and
|
||||||
@ -2783,8 +2799,11 @@ public final class Formatter implements Closeable, Flushable {
|
|||||||
try {
|
try {
|
||||||
// skip the trailing '$'
|
// skip the trailing '$'
|
||||||
index = Integer.parseInt(s, start, end - 1, 10);
|
index = Integer.parseInt(s, start, end - 1, 10);
|
||||||
|
if (index <= 0) {
|
||||||
|
throw new IllegalFormatArgumentIndexException(index);
|
||||||
|
}
|
||||||
} catch (NumberFormatException x) {
|
} catch (NumberFormatException x) {
|
||||||
assert(false);
|
throw new IllegalFormatArgumentIndexException(Integer.MIN_VALUE);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
index = 0;
|
index = 0;
|
||||||
@ -2811,7 +2830,7 @@ public final class Formatter implements Closeable, Flushable {
|
|||||||
if (width < 0)
|
if (width < 0)
|
||||||
throw new IllegalFormatWidthException(width);
|
throw new IllegalFormatWidthException(width);
|
||||||
} catch (NumberFormatException x) {
|
} catch (NumberFormatException x) {
|
||||||
assert(false);
|
throw new IllegalFormatWidthException(Integer.MIN_VALUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return width;
|
return width;
|
||||||
@ -2826,7 +2845,7 @@ public final class Formatter implements Closeable, Flushable {
|
|||||||
if (precision < 0)
|
if (precision < 0)
|
||||||
throw new IllegalFormatPrecisionException(precision);
|
throw new IllegalFormatPrecisionException(precision);
|
||||||
} catch (NumberFormatException x) {
|
} catch (NumberFormatException x) {
|
||||||
assert(false);
|
throw new IllegalFormatPrecisionException(Integer.MIN_VALUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return precision;
|
return precision;
|
||||||
|
@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020, 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. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package java.util;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unchecked exception thrown when the argument index is not within the valid
|
||||||
|
* range of supported argument index values. If an index value isn't
|
||||||
|
* representable by an {@code int} type, then the value
|
||||||
|
* {@code Integer.MIN_VALUE} will be used in the exception.
|
||||||
|
*
|
||||||
|
* @since 16
|
||||||
|
*/
|
||||||
|
class IllegalFormatArgumentIndexException extends IllegalFormatException {
|
||||||
|
|
||||||
|
@java.io.Serial
|
||||||
|
private static final long serialVersionUID = 4191767811181838112L;
|
||||||
|
|
||||||
|
private final int illegalIndex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an instance of this class with the specified argument index
|
||||||
|
* @param index The value of a corresponding illegal argument index.
|
||||||
|
*/
|
||||||
|
IllegalFormatArgumentIndexException(int index) {
|
||||||
|
illegalIndex = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the value of the illegal index.
|
||||||
|
* Returns {@code Integer.MIN_VALUE} if the illegal index is not
|
||||||
|
* representable by an {@code int}.
|
||||||
|
* @return the illegal index value
|
||||||
|
*/
|
||||||
|
int getIndex() {
|
||||||
|
return illegalIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMessage() {
|
||||||
|
int index = getIndex();
|
||||||
|
|
||||||
|
if (index == Integer.MIN_VALUE) {
|
||||||
|
return "Format argument index: (not representable as int)";
|
||||||
|
}
|
||||||
|
|
||||||
|
return String.format("Illegal format argument index = %d", getIndex());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -28,7 +28,9 @@ package java.util;
|
|||||||
/**
|
/**
|
||||||
* Unchecked exception thrown when the precision is a negative value other than
|
* Unchecked exception thrown when the precision is a negative value other than
|
||||||
* {@code -1}, the conversion does not support a precision, or the value is
|
* {@code -1}, the conversion does not support a precision, or the value is
|
||||||
* otherwise unsupported.
|
* otherwise unsupported. If the precision is not representable by an
|
||||||
|
* {@code int} type, then the value {@code Integer.MIN_VALUE} will be used
|
||||||
|
* in the exception.
|
||||||
*
|
*
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
@ -50,7 +52,8 @@ public class IllegalFormatPrecisionException extends IllegalFormatException {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the precision
|
* Returns the precision. If the precision isn't representable by an
|
||||||
|
* {@code int}, then will return {@code Integer.MIN_VALUE}.
|
||||||
*
|
*
|
||||||
* @return The precision
|
* @return The precision
|
||||||
*/
|
*/
|
||||||
|
@ -27,7 +27,9 @@ package java.util;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Unchecked exception thrown when the format width is a negative value other
|
* Unchecked exception thrown when the format width is a negative value other
|
||||||
* than {@code -1} or is otherwise unsupported.
|
* than {@code -1} or is otherwise unsupported. If a given format width is not
|
||||||
|
* representable by an {@code int} type, then the value
|
||||||
|
* {@code Integer.MIN_VALUE} will be used in the exception.
|
||||||
*
|
*
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
@ -49,7 +51,8 @@ public class IllegalFormatWidthException extends IllegalFormatException {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the width
|
* Returns the width. If the width is not representable by an {@code int},
|
||||||
|
* then returns {@code Integer.MIN_VALUE}.
|
||||||
*
|
*
|
||||||
* @return The width
|
* @return The width
|
||||||
*/
|
*/
|
||||||
|
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020, 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 8253459
|
||||||
|
* @run testng TestFormatSpecifierBounds
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
import static org.testng.Assert.*;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public class TestFormatSpecifierBounds {
|
||||||
|
|
||||||
|
public void testZeroIndex() {
|
||||||
|
IllegalFormatException e = expectThrows(IllegalFormatException.class, () -> {
|
||||||
|
String r = String.format("%0$s", "A", "B");
|
||||||
|
});
|
||||||
|
assertEquals(e.getMessage(), "Illegal format argument index = 0");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testNonRepresentableIntIndex() {
|
||||||
|
IllegalFormatException e = expectThrows(IllegalFormatException.class, () -> {
|
||||||
|
String r = String.format("%2147483648$s", "A", "B");
|
||||||
|
});
|
||||||
|
assertEquals(e.getMessage(), "Format argument index: (not representable as int)");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testZeroWidth() {
|
||||||
|
assertThrows(IllegalFormatException.class, () -> {
|
||||||
|
String r = String.format("%0s", "A", "B");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testNonRepresentableWidth() {
|
||||||
|
IllegalFormatException e = expectThrows(IllegalFormatException.class, () -> {
|
||||||
|
String r = String.format("%2147483648s", "A", "B");
|
||||||
|
});
|
||||||
|
assertEquals(e.getMessage(), Integer.toString(Integer.MIN_VALUE));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testNonRepresentablePrecision() {
|
||||||
|
IllegalFormatException e = expectThrows(IllegalFormatException.class, () -> {
|
||||||
|
String r = String.format("%.2147483648s", "A", "B");
|
||||||
|
});
|
||||||
|
assertEquals(e.getMessage(), Integer.toString(Integer.MIN_VALUE));
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user