[
https://issues.apache.org/jira/browse/WW-5836?focusedWorklogId=1052230&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-1052230
]
ASF GitHub Bot logged work on WW-5836:
--------------------------------------
Author: ASF GitHub Bot
Created on: 03/Nov/26 18:46
Start Date: 03/Nov/26 18:46
Worklog Time Spent: 10m
Work Description: lukaszlenart opened a new pull request, #2095:
URL: https://github.com/apache/struts/pull/2095
Fixes [WW-5836](https://issues.apache.org/jira/browse/WW-5836)
WW-5828 bounded the integer digits `StringConverter` emits for a
`BigDecimal`, falling back to `BigDecimal.toString()` past 340. Two other paths
format a `BigDecimal` without going through `StringConverter`, and neither
applied the bound:
- the `number` tag (`Number.end()`), which formats the value from the stack
with `NumberFormat` directly;
- `MessageFormat` arguments:
`AbstractLocalizedTextProvider.formatWithNullDetection` (reached from
`getText(key, args)`, `<s:text>` with `<s:param>`, and validator
`messageParams`) and `DefaultTextProvider.getText(key, defaultValue, List)`.
The bound and its check (`precision - scale`, computed in `long`) move to
`BigDecimalBounds`, shared by `StringConverter`, the number tag and message
formatting.
**Number tag.** Past the bound the value renders with `toString()`. The
tag's `maximumIntegerDigits` attribute is not a substitute, because
`DecimalFormat` applies it by dropping leading digits.
**Message arguments.** The argument itself cannot be replaced with a
`String`, because a typed element such as `{0,number}` throws
`IllegalArgumentException` on a String. Instead, when an argument is past the
bound, `BoundedMessageFormat` formats through a clone whose elements delegate
to their original formats and render the over-bound value with `toString()`.
`MessageFormat` re-parses a choice branch that contains `{n}` only when the
element's format is an actual `ChoiceFormat`. Wrapping a choice element would
therefore print the nested `{0}` literally, and leaving it unwrapped would
format the nested pattern without the bound. The wrapper repeats that step
itself, with the bound applied to the nested pattern at every level. A call
with no argument past the bound goes to `MessageFormat` unchanged.
Tests pin both sides of the bound for:
- the number tag, including `type="currency"`;
- plain `{0}`, `{0,number}` and `{0,number,currency}`;
- mixed elements (number pattern, String, date, `null`) next to an
over-bound argument;
- choice elements: nested one and two levels deep, a small choice argument
with an over-bound nested `{1}`, and a branch with no nested argument.
Below the bound, the output is compared byte for byte with plain
`MessageFormat`. Full core suite green (3633).
Observable change: a value with more than 340 integer digits renders in
`1E+340` form in these paths, as it already does through `StringConverter`. A
`{0,date}` element given such a value prints that form too, instead of a date
built from `longValue()`.
A 6.x backport follows in a separate PR.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Issue Time Tracking
-------------------
Worklog Id: (was: 1052230)
Remaining Estimate: 0h
Time Spent: 10m
> Number tag and localized text arguments do not bound integer digits when
> formatting BigDecimal
> ----------------------------------------------------------------------------------------------
>
> Key: WW-5836
> URL: https://issues.apache.org/jira/browse/WW-5836
> Project: Struts 2
> Issue Type: Bug
> Components: Core
> Reporter: Lukasz Lenart
> Assignee: Lukasz Lenart
> Priority: Major
> Fix For: 6.13.0, 7.5.0
>
> Time Spent: 10m
> Remaining Estimate: 0h
>
> WW-5828 bounded the number of integer digits {{StringConverter}} emits when
> it formats a {{BigDecimal}}, falling back to {{BigDecimal.toString()}} past
> the bound so that the length of the output follows the precision of the value
> rather than its scale.
> Two other places in core format a {{BigDecimal}} without going through
> {{StringConverter}}, and neither applies the same bound:
> * the {{number}} tag formats the value it finds on the stack with
> {{NumberFormat}} directly;
> * message arguments passed to {{getText(key, args)}} (also reached from the
> {{text}} tag with {{param}}, and from validator {{messageParams}}) are
> formatted by {{MessageFormat}}, which delegates numeric arguments to the
> locale {{NumberFormat}}.
> Apply the WW-5828 bound to both paths, sharing the bound rather than
> duplicating the constant. For message arguments the bound has to be applied
> through the formatter, not by substituting the argument, since a number-typed
> message element rejects a {{String}} argument. Values within the bound must
> render byte-identically to today, including {{currency}} and typed message
> elements.
> Same fix on the 6.x line.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)