Skip to content

Fixes Implicit narrowing conversion in compound assignment FloatToDecimal #1450

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

Open
wants to merge 1 commit into
base: 2.x
Choose a base branch
from

Conversation

odaysec
Copy link

@odaysec odaysec commented Jun 10, 2025


int len = flog10pow2(Integer.SIZE - numberOfLeadingZeros(f));


Fix the issue need to ensure that the type of the left-hand side (f) is at least as wide as the type of the right-hand side (pow10(H - len)). Since pow10 likely returns a long, the simplest and safest fix is to change the type of f from int to long. This avoids the implicit narrowing conversion and ensures that the computation can handle larger values without overflow.

Steps to implement the fix:

  1. Change the type of f from int to long in the method toChars.
  2. Update any other code within the method that interacts with f to ensure compatibility with the new type.
  3. Verify that the change does not introduce any unintended side effects or performance issues.

Compound assignment statements of the form x += y or x *= y perform an implicit narrowing conversion if the type of x is narrower than the type of y. x += y is equivalent to x = (T)(x + y), where T is the type of x. This can result in information loss and numeric errors such as overflows.

References

Compound Assignment Operators, Narrowing Primitive Conversion
NUM00-J. Detect or prevent integer overflow

@pjfanning
Copy link
Member

pjfanning commented Jun 10, 2025

@odaysec can you provide a test case that demos that this is a fix? A test case that fails with the existing code and that is fixed by your change.

@@ -405,14 +405,14 @@ private static int rop(long g, long cp) {
/*
Formats the decimal f 10^e.
*/
private int toChars(int f, int e) {
private int toChars(long f, int e) {
Copy link
Member

Choose a reason for hiding this comment

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

I can't find any calls to this method where the input f is long - they are all int. I think there will be a performance penalty here as there will need to be an implicit cast from int to long on all calls to this method after this change.

Copy link
Author

Choose a reason for hiding this comment

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

Hi @pjfanning

Thank you for the respond.

The reason I changed the parameter type from int to long was to address a potential integer overflow issue when handling large float values, particularly during conversion to a decimal representation. However, I understand the concern regarding the potential performance impact due to implicit casting from int to long on all existing calls to this method. If all current usages only involve int, I’m open to alternative approaches such as:

  • Introducing an overloaded method toChars(long f, int e) without removing the existing int version, to preserve performance for current usage patterns.
  • Re-evaluating whether long is truly necessary, or if overflow can be handled with validation before the call.

I’m happy to adjust the fix based on what would be best for both performance and maintainability. Please let me know your preferred direction.

Copy link
Member

Choose a reason for hiding this comment

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

I guess the start is to provide a broken test case. I'd prefer not to deal with theory and more interested in actual test cases.

Copy link
Member

@pjfanning pjfanning Jun 10, 2025

Choose a reason for hiding this comment

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

the code change doesn't even compile

Error:  COMPILATION ERROR : 
Error:  /home/runner/work/jackson-core/jackson-core/src/main/java/com/fasterxml/jackson/core/io/schubfach/FloatToDecimal.java:[415,63] incompatible types: possible lossy conversion from long to int

@cowtowncoder
Copy link
Member

Yeah we definitely need something to show a problem to solve, not a speculative fix without one.

This has bit of a smell of tool/scanner reported concern.

Also worth noting that code for "schubfach" is an outside contribution so if there's an issue, should probably be fixed there (but I don't remember specifically where it's from, @pjfanning may know).

@pjfanning
Copy link
Member

Yeah we definitely need something to show a problem to solve, not a speculative fix without one.

This has bit of a smell of tool/scanner reported concern.

Also worth noting that code for "schubfach" is an outside contribution so if there's an issue, should probably be fixed there (but I don't remember specifically where it's from, @pjfanning may know).

Comes from here: https://github.com/c4f7fcce9cb06515/Schubfach

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants