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

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

                Author: ASF GitHub Bot
            Created on: 20/May/26 06:16
            Start Date: 20/May/26 06:16
    Worklog Time Spent: 10m 
      Work Description: lukaszlenart opened a new pull request, #1693:
URL: https://github.com/apache/struts/pull/1693

   ## Summary
   
   Backports the [#1690](https://github.com/apache/struts/pull/1690) fix to the 
6.x line.
   
   The WW-5535 fix in #1593 made `DefaultActionProxy.resolveMethod()` report 
`isMethodSpecified()=true` for wildcard-resolved methods. That interacts with 
`HttpMethodInterceptor`'s `if/else-if` so the class-level annotation branch 
becomes unreachable when the resolved method carries no method-level annotation:
   
   \`\`\`java
   if (invocation.getProxy().isMethodSpecified()) {
       Method method = 
action.getClass().getMethod(invocation.getProxy().getMethod());
       if (AnnotationUtils.isAnnotatedBy(method, HTTP_METHOD_ANNOTATIONS)) {
           return doIntercept(invocation, method);
       }
       // unannotated method falls through silently
   } else if (AnnotationUtils.isAnnotatedBy(action.getClass(), 
HTTP_METHOD_ANNOTATIONS)) {
       return doIntercept(invocation, action.getClass()); // never reached
   }
   return invocation.invoke();
   \`\`\`
   
   **Affected scenario:**
   
   \`\`\`java
   @HttpPost // intends to restrict the whole action to POST
   public class OrderAction extends ActionSupport {
       public String create() { ... } // no method-level annotation
   }
   \`\`\`
   
   \`\`\`xml
   <action name=\"order-*\" class=\"com.example.OrderAction\" method=\"{1}\">
   \`\`\`
   
   `GET /order-create` resolves \`create()\` via wildcard, 
\`isMethodSpecified()=true\`, method has no annotation, the \`else-if\` never 
evaluates, and the class-level \`@HttpPost\` is ignored.
   
   ## Fix
   
   Convert \`else if\` to a standalone \`if\` so the class-level annotation 
check is always evaluated as a fallback when the method carries no annotation. 
Method-level annotations still take precedence (checked first, with early 
return). One-line structural change.
   
   ## Tests added
   
   Three new tests in `HttpMethodInterceptorTest`:
   
   - `testWildcardResolvedUnannotatedMethodRespectsClassLevelAnnotation` — GET 
rejected on a class annotated with `@AllowedHttpMethod(POST)` when the resolved 
method is unannotated.
   - `testWildcardResolvedUnannotatedMethodAllowsPostWithClassLevelAnnotation` 
— POST allowed on the same configuration.
   - `testWildcardResolvedExecuteRejectsGetThroughRealProxy` — integration 
coverage via a real `DefaultActionProxy` against `<action name=\"Wild-*\" 
method=\"{1}\">`, resolving to `ActionSupport.execute()`.
   
   ## Related
   
   - Original issue: [WW-5535](https://issues.apache.org/jira/browse/WW-5535)
   - 6.x line `DefaultActionProxy` change: #1593 (shipped in 6.9.0)
   - Same fix already merged to `main`: #1690 and follow-up integration test 
#1692
   
   ## Test plan
   
   - [x] \`./mvnw -pl core test -Dtest=HttpMethodInterceptorTest 
-DskipAssembly\` — 16/16 pass (13 pre-existing + 3 new)
   - [ ] CI green




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

    Worklog Id:     (was: 1021157)
    Time Spent: 1.5h  (was: 1h 20m)

> HttpMethodInterceptor does not work with action names using wildcards
> ---------------------------------------------------------------------
>
>                 Key: WW-5535
>                 URL: https://issues.apache.org/jira/browse/WW-5535
>             Project: Struts 2
>          Issue Type: Bug
>          Components: Core Interceptors
>    Affects Versions: 6.7.0, 7.0.0
>            Reporter: Riccardo Proserpio
>            Assignee: Lukasz Lenart
>            Priority: Major
>             Fix For: 6.9.0, 7.2.0
>
>          Time Spent: 1.5h
>  Remaining Estimate: 0h
>
> The ActionProxy.isMethodSpecified() method is documented as:
> {noformat}
> Gets status of the method value's initialization.
> Returns: true if the method returned by getMethod() is not a default 
> initializer value.
> {noformat}
> However, the implementation in DefaultActionProxy has a different behavior:
>  
> {code:java}
> private void resolveMethod() {
>     // if the method is set to null, use the one from the configuration
>     // if the one from the configuration is also null, use "execute"
>     if (StringUtils.isEmpty(this.method)) {
>         this.method = config.getMethodName();
>         if (StringUtils.isEmpty(this.method)) {
>             this.method = ActionConfig.DEFAULT_METHOD;
>         }
>         methodSpecified = false;
>     }
> } {code}
> methodSpecified is set to false not only if the default value is used, but 
> also \{*}if methodName is specified via config{*}.
> This method seems to have been introduced long ago as a patch for some DMI 
> behavior regression: WW-3628
> The issue happens for example if you specify an action like
> {code:java}
> <action name="example-*" class="aClass" method="aMethod"/>
> {code}
> since the method value is resolved later by wildcard matching.
> The HttpMethodInterceptor uses isSpecifiedMethods to decide when to process 
> the invocation:
>  
> {code:java}
> if (invocation.getProxy().isMethodSpecified()) {
>     Method method = 
> action.getClass().getMethod(invocation.getProxy().getMethod()); 
>     // doIntercept...
> }{code}
> thus skipping the validation for actionNames with wildcards.
> I'm not really sure if isMethodSpecified is wrong or has misleading 
> documentation. I'm not even sure why the HttpMethodInterceptor should skip 
> validation on the default execute methods.
> A fix might be just assessing the existence of 
> invocation.getProxy().getMethod() instead on relying on isMethodSpecified, 
> but before submitting a pr I'd like the opinion on the maintainers.



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

Reply via email to