[ 
https://issues.apache.org/jira/browse/WW-5729?focusedWorklogId=1041092&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-1041092
 ]

ASF GitHub Bot logged work on WW-5729:
--------------------------------------

                Author: ASF GitHub Bot
            Created on: 12/Sep/26 09:07
            Start Date: 12/Sep/26 09:07
    Worklog Time Spent: 10m 
      Work Description: lukaszlenart opened a new pull request, #1920:
URL: https://github.com/apache/struts/pull/1920

   Fixes [WW-5729](https://issues.apache.org/jira/browse/WW-5729)
   
   ## What
   
   `ValueStackShadowMap` in the `jasperreports` plugin is meant to fall back to 
`ValueStack.findValue(name)` for any report parameter not put in the map 
explicitly, so a parameter declared in the `.jasper` can be resolved straight 
from the action. Its `containsKey(String)` / `get(String)` were *overloads* of 
the `HashMap` methods, not overrides, and JasperReports — which holds the map 
as `java.util.Map` — calls the `Object` variants. The fallback therefore never 
ran: a declared parameter exposed only as an action property rendered as `null`.
   
   This is a regression: the `Object` overrides were the original code, 
`2908d746c` (2019, "Minor code optimization") narrowed them to `String` while 
adding the generics, and it first shipped in 6.0.0. The `jasperreports7` copy 
already has the `@Override` form.
   
   ## Changes
   
   - `jasperreports/ValueStackShadowMap`: `containsKey(Object)` / `get(Object)` 
are now real overrides; the `String` overloads stay as deprecated delegates for 
binary compatibility.
   - Both copies: an explicit map entry wins even when its value is `null`, so 
`containsKey` and `get` agree and JasperReports skips the parameter's 
default-value expression consistently.
   - Tests in both plugins: `$P{title}` resolved from an action getter with no 
`reportParameters` (watched failing with `null Report` before the fix), and an 
explicit `title → null` entry not shadowed by the getter.
   
   ## Behaviour change — for the version notes
   
   Users of the 6.x-line plugin whose reports declare a parameter with the same 
name as an action property (or a Struts context key such as `session`, 
`request`, `parameters`, `locale`) will see that parameter start resolving from 
the value stack instead of its default-value expression, as the class Javadoc 
has always described and as the `jasperreports7` plugin already does. The 
lookup is type-blind — a `Long` parameter meeting an `int` getter, or a 
`session` parameter meeting the Struts `SessionMap`, fails at fill time with a 
`ClassCastException`. Rename the report parameter or supply it through 
`reportParameters` in that case.
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)




Issue Time Tracking
-------------------

            Worklog Id:     (was: 1041092)
    Remaining Estimate: 0h
            Time Spent: 10m

> JasperReports plugin: ValueStackShadowMap overloads get/containsKey instead 
> of overriding them, so the value-stack fallback never reaches JasperReports
> -------------------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: WW-5729
>                 URL: https://issues.apache.org/jira/browse/WW-5729
>             Project: Struts 2
>          Issue Type: Bug
>          Components: Plugin - JasperReports
>            Reporter: Lukasz Lenart
>            Assignee: Lukasz Lenart
>            Priority: Minor
>             Fix For: 7.4.0
>
>          Time Spent: 10m
>  Remaining Estimate: 0h
>
> {{org.apache.struts2.views.jasperreports.ValueStackShadowMap}} (the 
> {{struts2-jasperreports-plugin}}, JasperReports 6.x line) is documented as a 
> {{HashMap}} whose {{containsKey}} and {{get}} fall back to 
> {{ValueStack.findValue(key)}} when the key is not in the map, so that a 
> report parameter declared in the {{.jasper}} can be resolved straight from 
> the action. That is how {{JasperReportsResult}} hands the parameter map to 
> {{JasperFillManager.fillReport}}.
> The two methods are declared as
> {code:java}public boolean containsKey(String key)
> public Object get(String key)
> {code}
> The {{HashMap}} methods they are meant to replace take {{Object}}, so these 
> are overloads, not overrides (the Javadoc says "overriding HashMap 
> implementation", and there is no {{@Override}}). JasperReports holds the 
> parameters as a {{java.util.Map}} and calls {{get(Object)}} / 
> {{containsKey(Object)}}, which resolve to the plain {{HashMap}} 
> implementation. The value-stack fallback therefore never runs when called 
> through JasperReports; only the entries the result puts explicitly 
> ({{reportDirectory}}, {{REPORT_LOCALE}}, {{REPORT_TIME_ZONE}}, and the 
> {{reportParameters}} map) reach the fill.
> The copy in the {{struts2-jasperreports7-plugin}} 
> ({{org.apache.struts2.views.jasperreports7.ValueStackShadowMap}}, WW-5455) 
> declares both methods with an {{Object}} parameter and {{@Override}}, so the 
> two plugins behave differently for the same report and action.
> Fix: change the parameter type to {{Object}} and add {{@Override}}, matching 
> the JR7 copy, with a test that fills a report whose declared parameter is 
> only available as an action property.
> Note this is a behaviour change for the 6.x plugin: after the fix, a declared 
> report parameter that the action exposes as a property but does not put in 
> {{reportParameters}} starts being resolved from the value stack, as the 
> Javadoc has always claimed. Worth a line in the version notes.
> Found while triaging WW-3245; no security impact (the fallback keys are the 
> parameter names compiled into the developer's {{.jasper}}, not request data).



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to