New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
8253459: Formatter treats index, width and precision > Integer.MAX_VALUE incorrectly #516
Conversation
👋 Welcome back igraves! A progress list of the required criteria for merging this PR into |
/csr needed |
@igraves this pull request will not be integrated until the CSR request JDK-8253875 for issue JDK-8253459 has been approved. |
Webrevs
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the new exception type useful? yes, it matches the previous pattern.
But it does not (and none of the IllegalFormatException subclasses) produce a readable message with the offending value. So the developer will not see anything useful.
The fine grained exceptions provide little value.
I've been on the fence about this, personally. The Formatter uses pretty fine-grained exception types for error conditions. I'd be okay discontinuing this practice here, but am not sure what to replace this with. Perhaps we enable |
33bf7a1
to
d4c3e37
Compare
Mailing list message from Jason Mehrens on i18n-dev: Ian, Should IllegalFormatArgumentIndexException.java provide an override of getMessage? It appears that is done in the following: https://github.com/openjdk/jdk/blob/9b07ef33b6e07afae1a8bfa034200eb3aab1f94f/src/java.base/share/classes/java/util/IllegalFormatWidthException.java Otherwise the index won't be rendered when toString or printStackTrace is invoked. Jason ________________________________________
Ian Graves has updated the pull request incrementally with one additional commit since the last revision: Tweaking verbiage ------------- Changes: Webrevs: Stats: 18 lines in 2 files changed: 0 ins; 5 del; 13 mod PR: https://git.openjdk.java.net/jdk/pull/516 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @Marcono1234, thanks for making a comment in an OpenJDK project!
All comments and discussions in the OpenJDK Community must be made available under the OpenJDK Terms of Use. If you already are an OpenJDK Author, Committer or Reviewer, please click here to open a new issue so that we can record that fact. Please Use "Add GitHub user Marcono1234 for the summary.
If you are not an OpenJDK Author, Committer or Reviewer, simply check the box below to accept the OpenJDK Terms of Use for your comments.
- I agree to the OpenJDK Terms of Use for all comments I make in a project in the OpenJDK GitHub organization.
Your comment will be automatically restored once you have accepted the OpenJDK Terms of Use.
* | ||
* <p> Values of <i>width</i> must be in the range one to | ||
* {@link Integer#MAX_VALUE}, inclusive, otherwise | ||
* {@link IllegalFormatWidthException} will be thrown |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @Marcono1234, thanks for making a comment in an OpenJDK project!
All comments and discussions in the OpenJDK Community must be made available under the OpenJDK Terms of Use. If you already are an OpenJDK Author, Committer or Reviewer, please click here to open a new issue so that we can record that fact. Please Use "Add GitHub user Marcono1234 for the summary.
If you are not an OpenJDK Author, Committer or Reviewer, simply check the box below to accept the OpenJDK Terms of Use for your comments.
- I agree to the OpenJDK Terms of Use for all comments I make in a project in the OpenJDK GitHub organization.
Your comment will be automatically restored once you have accepted the OpenJDK Terms of Use.
* {@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> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @Marcono1234, thanks for making a comment in an OpenJDK project!
All comments and discussions in the OpenJDK Community must be made available under the OpenJDK Terms of Use. If you already are an OpenJDK Author, Committer or Reviewer, please click here to open a new issue so that we can record that fact. Please Use "Add GitHub user Marcono1234 for the summary.
If you are not an OpenJDK Author, Committer or Reviewer, simply check the box below to accept the OpenJDK Terms of Use for your comments.
- I agree to the OpenJDK Terms of Use for all comments I make in a project in the OpenJDK GitHub organization.
Your comment will be automatically restored once you have accepted the OpenJDK Terms of Use.
@@ -2783,8 +2799,11 @@ private int index(String s, int start, int end) { | |||
try { | |||
// skip the trailing '$' | |||
index = Integer.parseInt(s, start, end - 1, 10); | |||
if(index <= 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @Marcono1234, thanks for making a comment in an OpenJDK project!
All comments and discussions in the OpenJDK Community must be made available under the OpenJDK Terms of Use. If you already are an OpenJDK Author, Committer or Reviewer, please click here to open a new issue so that we can record that fact. Please Use "Add GitHub user Marcono1234 for the summary.
If you are not an OpenJDK Author, Committer or Reviewer, simply check the box below to accept the OpenJDK Terms of Use for your comments.
- I agree to the OpenJDK Terms of Use for all comments I make in a project in the OpenJDK GitHub organization.
Your comment will be automatically restored once you have accepted the OpenJDK Terms of Use.
* 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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @Marcono1234, thanks for making a comment in an OpenJDK project!
All comments and discussions in the OpenJDK Community must be made available under the OpenJDK Terms of Use. If you already are an OpenJDK Author, Committer or Reviewer, please click here to open a new issue so that we can record that fact. Please Use "Add GitHub user Marcono1234 for the summary.
If you are not an OpenJDK Author, Committer or Reviewer, simply check the box below to accept the OpenJDK Terms of Use for your comments.
- I agree to the OpenJDK Terms of Use for all comments I make in a project in the OpenJDK GitHub organization.
Your comment will be automatically restored once you have accepted the OpenJDK Terms of Use.
|
||
/** | ||
* Gets the value of the illegal index. | ||
* Returns {@code Integer.MIN_VALUE} if the illegal index is not |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @Marcono1234, thanks for making a comment in an OpenJDK project!
All comments and discussions in the OpenJDK Community must be made available under the OpenJDK Terms of Use. If you already are an OpenJDK Author, Committer or Reviewer, please click here to open a new issue so that we can record that fact. Please Use "Add GitHub user Marcono1234 for the summary.
If you are not an OpenJDK Author, Committer or Reviewer, simply check the box below to accept the OpenJDK Terms of Use for your comments.
- I agree to the OpenJDK Terms of Use for all comments I make in a project in the OpenJDK GitHub organization.
Your comment will be automatically restored once you have accepted the OpenJDK Terms of Use.
@@ -28,7 +28,9 @@ | |||
/** | |||
* 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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @Marcono1234, thanks for making a comment in an OpenJDK project!
All comments and discussions in the OpenJDK Community must be made available under the OpenJDK Terms of Use. If you already are an OpenJDK Author, Committer or Reviewer, please click here to open a new issue so that we can record that fact. Please Use "Add GitHub user Marcono1234 for the summary.
If you are not an OpenJDK Author, Committer or Reviewer, simply check the box below to accept the OpenJDK Terms of Use for your comments.
- I agree to the OpenJDK Terms of Use for all comments I make in a project in the OpenJDK GitHub organization.
Your comment will be automatically restored once you have accepted the OpenJDK Terms of Use.
@@ -27,7 +27,9 @@ | |||
|
|||
/** | |||
* 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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @Marcono1234, thanks for making a comment in an OpenJDK project!
All comments and discussions in the OpenJDK Community must be made available under the OpenJDK Terms of Use. If you already are an OpenJDK Author, Committer or Reviewer, please click here to open a new issue so that we can record that fact. Please Use "Add GitHub user Marcono1234 for the summary.
If you are not an OpenJDK Author, Committer or Reviewer, simply check the box below to accept the OpenJDK Terms of Use for your comments.
- I agree to the OpenJDK Terms of Use for all comments I make in a project in the OpenJDK GitHub organization.
Your comment will be automatically restored once you have accepted the OpenJDK Terms of Use.
} | ||
|
||
/** | ||
* Gets the value of the illegal index. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @Marcono1234, thanks for making a comment in an OpenJDK project!
All comments and discussions in the OpenJDK Community must be made available under the OpenJDK Terms of Use. If you already are an OpenJDK Author, Committer or Reviewer, please click here to open a new issue so that we can record that fact. Please Use "Add GitHub user Marcono1234 for the summary.
If you are not an OpenJDK Author, Committer or Reviewer, simply check the box below to accept the OpenJDK Terms of Use for your comments.
- I agree to the OpenJDK Terms of Use for all comments I make in a project in the OpenJDK GitHub organization.
Your comment will be automatically restored once you have accepted the OpenJDK Terms of Use.
@@ -2783,8 +2799,11 @@ private int index(String s, int start, int end) { | |||
try { | |||
// skip the trailing '$' | |||
index = Integer.parseInt(s, start, end - 1, 10); | |||
if(index <= 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @Marcono1234, thanks for making a comment in an OpenJDK project!
All comments and discussions in the OpenJDK Community must be made available under the OpenJDK Terms of Use. If you already are an OpenJDK Author, Committer or Reviewer, please click here to open a new issue so that we can record that fact. Please Use "Add GitHub user Marcono1234 for the summary.
If you are not an OpenJDK Author, Committer or Reviewer, simply check the box below to accept the OpenJDK Terms of Use for your comments.
- I agree to the OpenJDK Terms of Use for all comments I make in a project in the OpenJDK GitHub organization.
Your comment will be automatically restored once you have accepted the OpenJDK Terms of Use.
* 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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @Marcono1234, thanks for making a comment in an OpenJDK project!
All comments and discussions in the OpenJDK Community must be made available under the OpenJDK Terms of Use. If you already are an OpenJDK Author, Committer or Reviewer, please click here to open a new issue so that we can record that fact. Please Use "Add GitHub user Marcono1234 for the summary.
If you are not an OpenJDK Author, Committer or Reviewer, simply check the box below to accept the OpenJDK Terms of Use for your comments.
- I agree to the OpenJDK Terms of Use for all comments I make in a project in the OpenJDK GitHub organization.
Your comment will be automatically restored once you have accepted the OpenJDK Terms of Use.
|
a84d3f2
to
4bcb053
Compare
Updates (including cleaning up some git weirdness with rebasing) include adherence to the new CSR draft proposal. This makes the new exception type package-private. |
return; | ||
} | ||
} | ||
throw new RuntimeException("Expected IllegalFormatException for zero argument index."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The wording of errors around exceptions can be misinterpreted. Did an expected exception occur or not?
If all you saw was the exception without the line of code, would it be unambiguous?
@@ -2783,8 +2799,11 @@ private int index(String s, int start, int end) { | |||
try { | |||
// skip the trailing '$' | |||
index = Integer.parseInt(s, start, end - 1, 10); | |||
if(index <= 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a space after 'if' please.
@@ -0,0 +1,98 @@ | |||
/* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typically, using the TestNG framework is preferable for new tests.
In addition to a convenient set of Asserts that check and print expected vs actual and message
it includes patterns for testing for expected exceptions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, these tests are amenable to TestNG's assertThrows
method. That might be all you need; we generally aren't too concerned about the exact content and formatting of the exception's message. However, if you want to make additional assertions over the thrown exception, it can be obtained using expectThrows
instead of assertThrows
.
throw new RuntimeException("Expected IllegalFormatException for non-representable precision."); | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a newline at end-of-file.
@Override | ||
public String getMessage() { | ||
return String.format("Illegal format argument index = %d", getIndex()); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The exception with a very large negative number isn't going to easy to recognize.
Can the exception message say (for the Integer.MIN_VALUE) that the index is not valid index.
Its probably too much to ask have an indication where in the format string the offending index occurs.
int index = getIndex(); | ||
|
||
if (index == Integer.MIN_VALUE) { | ||
return "Format argument index: (unrepresentable as int)"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps "(not representable as int)" is more readable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After reading it a few times, I agree.
@igraves This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 87 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. As you do not have Committer status in this project an existing Committer must agree to sponsor your change. Possible candidates are the reviewers of this PR (@RogerRiggs, @stuart-marks) but any other Committer may sponsor as well. ➡️ To flag this PR as ready for integration with the above commit message, type |
IllegalFormatException e = expectThrows(IllegalFormatException.class, () -> { | ||
String r = String.format("%2147483648$s", "A", "B"); | ||
}); | ||
//assertEquals(e.getMessage(), "Illegal format argument index = " + Integer.MIN_VALUE); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extraneous comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So it would seem!
/integrate |
/sponsor |
@stuart-marks @igraves Since your change was applied there have been 87 commits pushed to the
Your commit was automatically rebased without conflicts. Pushed as commit 080c707. 💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored. |
…LUE incorrectly Reviewed-by: rriggs, smarks
The
java.util.Formatter
format specifies support for field widths, argument indexes, or precision lengths of a field that relate to the variadic arguments supplied to the formatter. These numbers are specified by integers, sometimes negative. For argument index, it's specified in the documentation that the highest allowed argument is limited by the largest possible index of an array (ie the largest possible variadic index), but for the other two it's not defined. Moreover, what happens when a number field in a string is too large or too small to be represented by a 32-bit integer type is not defined.This fix adds documentation to specify what error behavior occurs during these cases. Additionally it adds an additional exception type to throw when an invalid argument index is observed.
A CSR will be required for this PR.
Progress
Testing
Issue
Reviewers
Download
$ git fetch https://git.openjdk.java.net/jdk pull/516/head:pull/516
$ git checkout pull/516