You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@struts.apache.org by GitBox <gi...@apache.org> on 2021/11/11 22:31:16 UTC

[GitHub] [struts] davoustp commented on pull request #504: Cache all OGNL expressions (when enabled) irrespective of their execution status [Fixes WW-5147]

davoustp commented on pull request #504:
URL: https://github.com/apache/struts/pull/504#issuecomment-966671933


   Very good question, indeed. ;-)
   
   This is because this single expression can be evaluated through a chain, and the way the method {{ognl.ASTChain.getValueBody(OgnlContext, Object)}} is built can lead to method {{ognl.OgnlRuntime.getProperty(OgnlContext, Object, Object)}} throwing a {{OgnlException("source is null for getProperty(null, \"" + name + "\")")}} (line 2733).
   Hence the expression is not cached, before this code change.
   
   Here a stack trace of the such an occurence (Struts 2.5.20):
   `Daemon Thread [http-nio-8080-exec-6] (Suspended (breakpoint at line 2733 in OgnlRuntime))   
       owns: NioEndpoint$NioSocketWrapper  (id=294)    
       OgnlRuntime.getProperty(OgnlContext, Object, Object) line: 2733 
       ASTProperty.getValueBody(OgnlContext, Object) line: 114 
       ASTProperty(SimpleNode).evaluateGetValueBody(OgnlContext, Object) line: 212 
       ASTProperty(SimpleNode).getValue(OgnlContext, Object) line: 258 
       ASTChain.getValueBody(OgnlContext, Object) line: 141    
       ASTChain(SimpleNode).evaluateGetValueBody(OgnlContext, Object) line: 212    
       ASTChain(SimpleNode).getValue(OgnlContext, Object) line: 258    
       Ognl.getValue(Object, Map, Object, Class) line: 470 
       Ognl.getValue(Object, Map, Object) line: 434    
       OgnlUtil$2.execute(Object) line: 401    
       OgnlUtil.compileAndExecute(String, Map<String,Object>, OgnlTask<T>) line: 442   
       OgnlUtil.getValue(String, Map<String,Object>, Object) line: 399 
       OgnlValueStack.getValueUsingOgnl(String) line: 293  
       OgnlValueStack.tryFindValue(String) line: 276   
       OgnlValueStack.tryFindValueWhenExpressionIsNotNull(String) line: 258    
       OgnlValueStack.findValue(String, boolean) line: 238 
       OgnlValueStack.findValue(String) line: 300  
       StrutsRequestWrapper.getAttribute(String) line: 94  
   ...`
   
   And a few values of the {{name}} attribute of method {{ognl.OgnlRuntime.getProperty(OgnlContext, Object, Object)}} creating this scenario:
   `actionMapping
   opensymphony
   apache
   valueStack
   actiontag
   servlet
   Application__
   Request__`
   
   And finally a stack trace for the {{actionMapping}} case:
   `Daemon Thread [http-nio-8080-exec-6] (Suspended (breakpoint at line 2733 in OgnlRuntime))   
       owns: NioEndpoint$NioSocketWrapper  (id=294)    
       OgnlRuntime.getProperty(OgnlContext, Object, Object) line: 2733 
       ASTProperty.getValueBody(OgnlContext, Object) line: 114 
       ASTProperty(SimpleNode).evaluateGetValueBody(OgnlContext, Object) line: 212 
       ASTProperty(SimpleNode).getValue(OgnlContext, Object) line: 258 
       ASTChain.getValueBody(OgnlContext, Object) line: 141    
       ASTChain(SimpleNode).evaluateGetValueBody(OgnlContext, Object) line: 212    
       ASTChain(SimpleNode).getValue(OgnlContext, Object) line: 258    
       Ognl.getValue(Object, Map, Object, Class) line: 470 
       Ognl.getValue(Object, Map, Object) line: 434    
       OgnlUtil$2.execute(Object) line: 401    
       OgnlUtil.compileAndExecute(String, Map<String,Object>, OgnlTask<T>) line: 442   
       OgnlUtil.getValue(String, Map<String,Object>, Object) line: 399 
       OgnlValueStack.getValueUsingOgnl(String) line: 293  
       OgnlValueStack.tryFindValue(String) line: 276   
       OgnlValueStack.tryFindValueWhenExpressionIsNotNull(String) line: 258    
       OgnlValueStack.findValue(String, boolean) line: 238 
       OgnlValueStack.findValue(String) line: 300  
       StrutsRequestWrapper.getAttribute(String) line: 94  
       PrepareOperations.findActionMapping(HttpServletRequest, HttpServletResponse, boolean) line: 181 
       PrepareOperations.findActionMapping(HttpServletRequest, HttpServletResponse) line: 165  
       StrutsPrepareFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 90 
       ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 189  
       ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 162  
   ...`
   
   Here, the Struts layer attempts to find the {{actionMapping}} to use, which is first evaluated using OGNL onto the ValueStack - and in this specific case, there is no such entry in the stack - before it actually gets into the struts configuration to find the appropriate mapping.
   
   I did spent some time to check how method {{ognl.ASTChain.getValueBody(OgnlContext, Object)}} works, and I'm actually puzzled to see that the {{source}} attribute is actually the result of the previous step in the chain (which can be null, leading to the exception being raised). But I'm not sure whether this is a problem or a by-design choice (and I sure don't have enough background onto the OGNL internals to decide).
   
   Would you say that this sequence of event is normal, or is it something that should not occur?
   
   Let me know, and I'll open another issue - I can reproduce it 100% so it's easy to investigate if you find it useful...


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@struts.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org