WW-5697 Restrict the indexed-access fast path in XWorkMethodAccessor to real indexed properties - #1871
Open
lukaszlenart wants to merge 3 commits into
Open
WW-5697 Restrict the indexed-access fast path in XWorkMethodAccessor to real indexed properties#1871lukaszlenart wants to merge 3 commits into
lukaszlenart wants to merge 3 commits into
Conversation
…xed properties XWorkMethodAccessor.callMethod skipped the denyMethodExecution check for any method whose name began with "get" and took one argument, or "set" and took two. That test is a name prefix plus an argument count, not a property check, so an ordinary method such as getSomething(String) qualified and was executed during parameter binding with the argument supplied in the parameter name. The fast path now applies only where the target type genuinely declares an indexed property accessor, determined with OgnlRuntime.getIndexedPropertyType. Anything else falls through to the existing denyMethodExecution check. Both int-indexed and object-indexed accessors continue to work. The new tests cover those two, the argument-taking method that must now be blocked while method execution is denied, and the unset-flag path where methods still execute as before, so the change is confined to parameter binding. DENY_INDEXED_ACCESS_EXECUTION is left in place for now; it is public API and is never set anywhere, so its removal is handled separately. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Nothing in the framework has ever written this key, so the check it guarded in XWorkMethodAccessor never fired. Now that indexed property access is identified from the target type rather than from a method name prefix, the flag has nothing left to guard. It is public API, so it is deprecated here rather than deleted, and removal is tracked for 8.0.0 in WW-5699. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Merge the nested indexed-property check into the enclosing condition (S1066) and give the deprecation its since/forRemoval arguments (S6355). Also cover the branch that rejects a method with nothing left after the "get" prefix, using a map style get(String) accessor. That is worth asserting in its own right: such a method is not an indexed property accessor, so it must not be executed while method execution is denied. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Fixes WW-5697
Problem
XWorkMethodAccessor.callMethod(...)skipped thedenyMethodExecutioncheck for any method whose name began withgetand took one argument, orsetand took two:That is a name prefix plus an argument count, not a property check. An ordinary method such as
getSomething(String)is not a JavaBeans property, but it matches, so it was executed during parameter binding with the argument taken from the parameter name — a parameter name ofgetSomething('value').propertycallsgetSomething("value").The flag the branch consults,
DENY_INDEXED_ACCESS_EXECUTION, is never written anywhere in main source, soexecis alwaysnulland the fast path is unconditional.Change
The fast path now applies only where the target type genuinely declares an indexed property accessor, determined with
OgnlRuntime.getIndexedPropertyType(...). Everything else falls through to the existingdenyMethodExecutioncheck.Note the check is keyed on the property name while
callMethodreceives the method name, hence the prefix strip andIntrospector.decapitalize.DENY_INDEXED_ACCESS_EXECUTIONis public API, so it is deprecated here rather than deleted; removal in 8.0.0 is tracked as WW-5699.Scope of the behaviour change
Confined to parameter binding. The fast path only matters when the deny flag is set, and that flag is set only by
ParametersInterceptor,AliasInterceptorandStaticParametersInterceptor— with it unset, such a call already fell through to the check below and executed. JSP and tag rendering are unaffected.Both kinds of indexed accessor keep working. Worth knowing for review: a classic
getItem(int)/setItem(int, String)pair reports asINDEXED_PROPERTY_OBJECT, notINDEXED_PROPERTY_INT, so the predicate has to be!= INDEXED_PROPERTY_NONE— anINT-only rule would break the very case the original hack exists to serve.Tests
XWorkMethodAccessorTestis new and covers four behaviours:The two indexed-property tests were mutation-checked: forcing the new predicate to always reject fails exactly those two, so they are not passing vacuously.
Full
coresuite green: 3201 tests, 0 failures, 0 errors.Related
WW-5698 covers a separate issue found alongside this one — the
ModelDrivenexemption inStrutsParameterAuthorizeralso exempting the action's own members. Different cause, different fix, not addressed here. An end-to-endModelDrivenbinding test was deliberately left out of this PR because it would couple these tests to the exemption WW-5698 is expected to change.🤖 Generated with Claude Code