Skip to content
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

8264161: BigDecimal#stripTrailingZeros can throw undocumented ArithmeticException #3189

Closed
wants to merge 1 commit into from

Conversation

@fmeum
Copy link

@fmeum fmeum commented Mar 25, 2021

Adds missing @throws declarations for ArithmeticException to the public
function
java.math.BigDecimal#stripTrailingZeros
as well as the private helper functions
java.math.BigDecimal#createAndStripZerosToMatchScale(long, int, long)
java.math.BigDecimal#createAndStripZerosToMatchScale(BigInteger, int, long)

stripTrailingZeros calls one of the two helper functions, both of which
can repeatedly decrease the scale by 1 until it underflows. If it does,
the call to checkScale will result in an ArithmeticException (overflow).


Progress

  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue
  • Change must be properly reviewed

Issue

  • JDK-8264161: BigDecimal#stripTrailingZeros can throw undocumented ArithmeticException ⚠️ Issue is not open.

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.java.net/jdk pull/3189/head:pull/3189
$ git checkout pull/3189

Update a local copy of the PR:
$ git checkout pull/3189
$ git pull https://git.openjdk.java.net/jdk pull/3189/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 3189

View PR using the GUI difftool:
$ git pr show -t 3189

Using diff file

Download this PR as a diff file:
https://git.openjdk.java.net/jdk/pull/3189.diff

…gZeros

Adds missing @throws declarations for ArithmeticException to the public
function
java.math.BigDecimal#stripTrailingZeros
as well as the private helper functions
java.math.BigDecimal#createAndStripZerosToMatchScale(long, int, long)
java.math.BigDecimal#createAndStripZerosToMatchScale(BigInteger, int, long)

stripTrailingZeros calls one of the two helper functions, both of which
can repeatedly decrease the scale by 1 until it underflows. If it does,
the call to checkScale will result in an ArithmeticException (overflow).
@bridgekeeper bridgekeeper bot added the oca label Mar 25, 2021
@bridgekeeper
Copy link

@bridgekeeper bridgekeeper bot commented Mar 25, 2021

Hi @fmeum, welcome to this OpenJDK project and thanks for contributing!

We do not recognize you as Contributor and need to ensure you have signed the Oracle Contributor Agreement (OCA). If you have not signed the OCA, please follow the instructions. Please fill in your GitHub username in the "Username" field of the application. Once you have signed the OCA, please let us know by writing /signed in a comment in this pull request.

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 fmeum" as summary for the issue.

If you are contributing this work on behalf of your employer and your employer has signed the OCA, please let us know by writing /covered in a comment in this pull request.

@fmeum fmeum changed the title 8264161: ArithmeticException not declared for BigDecimal#stripTrailingZeros 8264161: BigDecimal#stripTrailingZeros can throw undocumented ArithmeticException Mar 25, 2021
@openjdk
Copy link

@openjdk openjdk bot commented Mar 25, 2021

@fmeum The following label will be automatically applied to this pull request:

  • core-libs

When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command.

@openjdk openjdk bot added the core-libs label Mar 25, 2021
@fmeum
Copy link
Author

@fmeum fmeum commented Mar 31, 2021

/signed

@bridgekeeper
Copy link

@bridgekeeper bridgekeeper bot commented Mar 31, 2021

Thank you! Please allow for up to two weeks to process your OCA, although it is usually done within one to two business days. Also, please note that pull requests that are pending an OCA check will not usually be evaluated, so your patience is appreciated!

@fmeum
Copy link
Author

@fmeum fmeum commented Mar 31, 2021

/covered

@bridgekeeper
Copy link

@bridgekeeper bridgekeeper bot commented Mar 31, 2021

Thank you! Please allow for a few business days to verify that your employer has signed the OCA. Also, please note that pull requests that are pending an OCA check will not usually be evaluated, so your patience is appreciated!

@robilad
Copy link

@robilad robilad commented Apr 9, 2021

Hi, please send me an e-mail at Dalibor.topic@oracle.com so that I can verify your account.

@fmeum
Copy link
Author

@fmeum fmeum commented Apr 21, 2021

/covered

@bridgekeeper
Copy link

@bridgekeeper bridgekeeper bot commented Apr 21, 2021

Already processed the covered command

@mlbridge
Copy link

@mlbridge mlbridge bot commented Apr 21, 2021

Webrevs

@RogerRiggs
Copy link
Contributor

@RogerRiggs RogerRiggs commented Apr 21, 2021

Please note the issue 8264161 has already been addressed by:
#3204

@fmeum
Copy link
Author

@fmeum fmeum commented Apr 21, 2021

Please note the issue 8264161 has already been addressed by:
#3204

@RogerRiggs The fix in #3204 remains incomplete as it does not update the @throws declarations. I could open a new bug for that, but unfortunately the form at https://bugreport.java.com/bugreport/start_form.do appears to be down: There is no server response when clicking "Submit", the request to https://bugreport.java.com/bugreport/submit_start.do just hangs forever.

@mlbridge
Copy link

@mlbridge mlbridge bot commented Apr 21, 2021

Mailing list message from Brian Burkhalter on core-libs-dev:

On Apr 21, 2021, at 9:14 AM, Fabian Meumertzheim <github.com+4312191+fmeum at openjdk.java.net<mailto:github.com+4312191+fmeum at openjdk.java.net>> wrote:

On Thu, 25 Mar 2021 08:19:24 GMT, Fabian Meumertzheim <github.com+4312191+fmeum at openjdk.org<mailto:github.com+4312191+fmeum at openjdk.org>> wrote:

Adds missing @throws declarations for ArithmeticException to the public
function
java.math.BigDecimal#stripTrailingZeros
as well as the private helper functions
java.math.BigDecimal#createAndStripZerosToMatchScale(long, int, long)
java.math.BigDecimal#createAndStripZerosToMatchScale(BigInteger, int, long)

stripTrailingZeros calls one of the two helper functions, both of which
can repeatedly decrease the scale by 1 until it underflows. If it does,
the call to checkScale will result in an ArithmeticException (overflow).

Please note the issue [8264161](https://bugs.openjdk.java.net/browse/JDK-8264161) has already been addressed by:
#3204

@RogerRiggs The fix in #3204 remains incomplete as it does not update the `@throws` declarations. I could open a new bug for that, but unfortunately the form at https://bugreport.java.com/bugreport/start_form.do appears to be down: There is no server response when clicking "Submit", the request to https://bugreport.java.com/bugreport/submit_start.do just hangs forever.

There is in fact some system maintenance which should be completed this morning, Pacific Time. After that a new issue for this should be filed as we cannot reuse issue IDs.

Thanks.

1 similar comment
@mlbridge
Copy link

@mlbridge mlbridge bot commented Apr 21, 2021

Mailing list message from Brian Burkhalter on core-libs-dev:

On Apr 21, 2021, at 9:14 AM, Fabian Meumertzheim <github.com+4312191+fmeum at openjdk.java.net<mailto:github.com+4312191+fmeum at openjdk.java.net>> wrote:

On Thu, 25 Mar 2021 08:19:24 GMT, Fabian Meumertzheim <github.com+4312191+fmeum at openjdk.org<mailto:github.com+4312191+fmeum at openjdk.org>> wrote:

Adds missing @throws declarations for ArithmeticException to the public
function
java.math.BigDecimal#stripTrailingZeros
as well as the private helper functions
java.math.BigDecimal#createAndStripZerosToMatchScale(long, int, long)
java.math.BigDecimal#createAndStripZerosToMatchScale(BigInteger, int, long)

stripTrailingZeros calls one of the two helper functions, both of which
can repeatedly decrease the scale by 1 until it underflows. If it does,
the call to checkScale will result in an ArithmeticException (overflow).

Please note the issue [8264161](https://bugs.openjdk.java.net/browse/JDK-8264161) has already been addressed by:
#3204

@RogerRiggs The fix in #3204 remains incomplete as it does not update the `@throws` declarations. I could open a new bug for that, but unfortunately the form at https://bugreport.java.com/bugreport/start_form.do appears to be down: There is no server response when clicking "Submit", the request to https://bugreport.java.com/bugreport/submit_start.do just hangs forever.

There is in fact some system maintenance which should be completed this morning, Pacific Time. After that a new issue for this should be filed as we cannot reuse issue IDs.

Thanks.

@mlbridge
Copy link

@mlbridge mlbridge bot commented Apr 21, 2021

Mailing list message from Brian Burkhalter on core-libs-dev:

On Apr 21, 2021, at 9:23 AM, Brian Burkhalter <brian.burkhalter at oracle.com<mailto:brian.burkhalter at oracle.com>> wrote:

There is in fact some system maintenance which should be completed this morning, Pacific Time. After that a new issue for this should be filed as we cannot reuse issue IDs.

Correction: not sure about system maintenance (dates confused). Sorry.

1 similar comment
@mlbridge
Copy link

@mlbridge mlbridge bot commented Apr 21, 2021

Mailing list message from Brian Burkhalter on core-libs-dev:

On Apr 21, 2021, at 9:23 AM, Brian Burkhalter <brian.burkhalter at oracle.com<mailto:brian.burkhalter at oracle.com>> wrote:

There is in fact some system maintenance which should be completed this morning, Pacific Time. After that a new issue for this should be filed as we cannot reuse issue IDs.

Correction: not sure about system maintenance (dates confused). Sorry.

@mlbridge
Copy link

@mlbridge mlbridge bot commented Apr 21, 2021

Mailing list message from Joe Darcy on core-libs-dev:

On 4/21/2021 9:14 AM, Fabian Meumertzheim wrote:

On Thu, 25 Mar 2021 08:19:24 GMT, Fabian Meumertzheim <github.com+4312191+fmeum at openjdk.org> wrote:

Adds missing @throws declarations for ArithmeticException to the public
function
java.math.BigDecimal#stripTrailingZeros
as well as the private helper functions
java.math.BigDecimal#createAndStripZerosToMatchScale(long, int, long)
java.math.BigDecimal#createAndStripZerosToMatchScale(BigInteger, int, long)

stripTrailingZeros calls one of the two helper functions, both of which
can repeatedly decrease the scale by 1 until it underflows. If it does,
the call to checkScale will result in an ArithmeticException (overflow).
Please note the issue [8264161](https://bugs.openjdk.java.net/browse/JDK-8264161) has already been addressed by:
#3204
@RogerRiggs The fix in #3204 remains incomplete as it does not update the `@throws` declarations. I could open a new bug for that, but unfortunately the form at https://bugreport.java.com/bugreport/start_form.do appears to be down: There is no server response when clicking "Submit", the request to https://bugreport.java.com/bugreport/submit_start.do just hangs forever.

Just was we don't think it is helpful to put an explicit

@throws NullPointerException if a argument is null

on every method that throws a NPE for a null argument, I don't think it
is helpful or necessary to explicitly note in every BigDecimal method
with rounding that it could throw ArithmeticException. The general
class-level statement

?* <p>As a 32-bit integer, the set of values for the scale is large,
?* but bounded. If the scale of a result would exceed the range of a
?* 32-bit integer, either by overflow or underflow, the operation may
?* throw an {@code ArithmeticException}.

in meant to capture the needed information.

-Joe

1 similar comment
@mlbridge
Copy link

@mlbridge mlbridge bot commented Apr 21, 2021

Mailing list message from Joe Darcy on core-libs-dev:

On 4/21/2021 9:14 AM, Fabian Meumertzheim wrote:

On Thu, 25 Mar 2021 08:19:24 GMT, Fabian Meumertzheim <github.com+4312191+fmeum at openjdk.org> wrote:

Adds missing @throws declarations for ArithmeticException to the public
function
java.math.BigDecimal#stripTrailingZeros
as well as the private helper functions
java.math.BigDecimal#createAndStripZerosToMatchScale(long, int, long)
java.math.BigDecimal#createAndStripZerosToMatchScale(BigInteger, int, long)

stripTrailingZeros calls one of the two helper functions, both of which
can repeatedly decrease the scale by 1 until it underflows. If it does,
the call to checkScale will result in an ArithmeticException (overflow).
Please note the issue [8264161](https://bugs.openjdk.java.net/browse/JDK-8264161) has already been addressed by:
#3204
@RogerRiggs The fix in #3204 remains incomplete as it does not update the `@throws` declarations. I could open a new bug for that, but unfortunately the form at https://bugreport.java.com/bugreport/start_form.do appears to be down: There is no server response when clicking "Submit", the request to https://bugreport.java.com/bugreport/submit_start.do just hangs forever.

Just was we don't think it is helpful to put an explicit

@throws NullPointerException if a argument is null

on every method that throws a NPE for a null argument, I don't think it
is helpful or necessary to explicitly note in every BigDecimal method
with rounding that it could throw ArithmeticException. The general
class-level statement

?* <p>As a 32-bit integer, the set of values for the scale is large,
?* but bounded. If the scale of a result would exceed the range of a
?* 32-bit integer, either by overflow or underflow, the operation may
?* throw an {@code ArithmeticException}.

in meant to capture the needed information.

-Joe

@fmeum
Copy link
Author

@fmeum fmeum commented Apr 21, 2021

Just was we don't think it is helpful to put an explicit

@throws NullPointerException if a argument is null

on every method that throws a NPE for a null argument, I don't think it
is helpful or necessary to explicitly note in every BigDecimal method
with rounding that it could throw ArithmeticException. The general
class-level statement

?*

As a 32-bit integer, the set of values for the scale is large,
?* but bounded. If the scale of a result would exceed the range of a
?* 32-bit integer, either by overflow or underflow, the operation may
?* throw an {@code ArithmeticException}.

in meant to capture the needed information.

-Joe

I do agree with this in general, but I think that the situation at hand is a bit different from your example for two reasons:

  • The BigDecimal class already contains many explicit @throws annotations for RuntimeExceptions. The absence of such an annotation from a particular method would thus naturally be interpreted as saying that the method does not throw.
  • For someone not intimately familiar with the internal representation of BigDecimals, it is probably quite unexpected that a function called stripTrailingZeros would perform rounding and thus be liable to scale overflows. (This is what happened to the maintainers of jackson-core, where this lead to an unexpected RuntimeException that was only discovered via fuzzing. They simply took this function to perform some kind of "harmless" canonicalization.)

That is why I do see value in adding these annotations in this particular case.

@jddarcy
Copy link
Member

@jddarcy jddarcy commented Apr 21, 2021

Just was we don't think it is helpful to put an explicit
@throws NullPointerException if a argument is null
on every method that throws a NPE for a null argument, I don't think it
is helpful or necessary to explicitly note in every BigDecimal method
with rounding that it could throw ArithmeticException. The general
class-level statement
?* As a 32-bit integer, the set of values for the scale is large,
?* but bounded. If the scale of a result would exceed the range of a
?* 32-bit integer, either by overflow or underflow, the operation may
?* throw an {@code ArithmeticException}.
in meant to capture the needed information.
-Joe

I do agree with this in general, but I think that the situation at hand is a bit different from your example for two reasons:

* The `BigDecimal` class already contains many explicit `@throws` annotations for `RuntimeException`s. The absence of such an annotation from a particular method would thus naturally be interpreted as saying that the method does not throw.

* For someone not intimately familiar with the internal representation of `BigDecimal`s, it is probably quite unexpected that a function called `stripTrailingZeros` would perform rounding and thus be liable to scale overflows. (This is what happened to the maintainers of jackson-core, where this lead to an unexpected RuntimeException that was only discovered via fuzzing. They simply took this function to perform some kind of "harmless" canonicalization.)

That is why I do see value in adding these annotations in this particular case.

Thanks for the additional context. Fuzzers would be likely to run into an exception from stripTrailingZeros as they would be likely to start with extreme exponent values.

Looking over BigDecimal's throws clauses more closely, I've filed

JDK-8265700: Regularize throws clauses in BigDecimal

and will send out a PR shortly. This change will add a throws clause for the unexpected exception from stripTrailingZeros and remove several "throws ArithmeticException when rounding occurs and the rounding mode is UNNECESSARY" clauses.

@fmeum
Copy link
Author

@fmeum fmeum commented Apr 22, 2021

Thanks!

@fmeum fmeum closed this Apr 22, 2021
@fmeum fmeum deleted the jdk-8264161 branch Apr 22, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
4 participants