Uploaded image for project: 'Commons JEXL'
  1. Commons JEXL
  2. JEXL-217

Interpreter.getAttribute() raises exception in non-strict mode when cached property resolver is used

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • 3.0
    • 3.1
    • None

    Description

      I'm chasing strange bug where regardless of the JexlContext operating in non-strict mode the ArrayIndexOutOfBoundsException is thrown in the script like this

      entity = args[0]; @lenient {copy = args[1]; xwsp = args[2]}
      

      here is the stack trace

      Caused by: java.lang.ArrayIndexOutOfBoundsException
      at java.lang.reflect.Array.get(Native Method)
      at org.apache.commons.jexl3.internal.introspection.ListGetExecutor.tryInvoke(ListGetExecutor.java:88)
      at org.apache.commons.jexl3.internal.Interpreter.getAttribute(Interpreter.java:1700)
      at org.apache.commons.jexl3.internal.Interpreter.visit(Interpreter.java:945)
      at org.apache.commons.jexl3.parser.ASTArrayAccess.jjtAccept(ASTArrayAccess.java:18)
      at org.apache.commons.jexl3.internal.Interpreter.visit(Interpreter.java:1013)
      at org.apache.commons.jexl3.parser.ASTReference.jjtAccept(ASTReference.java:18)
      at org.apache.commons.jexl3.internal.Interpreter.executeAssign(Interpreter.java:1119)
      at org.apache.commons.jexl3.internal.Interpreter.visit(Interpreter.java:1062)
      at org.apache.commons.jexl3.parser.ASTAssignment.jjtAccept(ASTAssignment.java:18)
      at org.apache.commons.jexl3.internal.Interpreter.visit(Interpreter.java:578)
      at org.apache.commons.jexl3.parser.ASTBlock.jjtAccept(ASTBlock.java:18)
      at org.apache.commons.jexl3.internal.Interpreter.processAnnotation(Interpreter.java:1848)
      at org.apache.commons.jexl3.internal.Interpreter$1.call(Interpreter.java:1856)

      Unfortunately I haven't managed to create and provide reproducible test case, but from looking into the code I think the problem fires when the Interpreter tries to call cached method ListGetExecutor.tryInvoke() but does not catch subsequent exception.

      I rewrote the code as follows and the problem seemed to go away

      Interpreter.java
              ...
              Exception xcause = null;
      
              // attempt to reuse last executor cached in volatile JexlNode.value
              if (node != null && cache) {
                  Object cached = node.jjtGetValue();
                  if (cached instanceof JexlPropertyGet) {
                      JexlPropertyGet vg = (JexlPropertyGet) cached;
      
                      try {
      
                         Object value = vg.tryInvoke(object, attribute);
                         if (!vg.tryFailed(value)) {
                             return value;
                         }
      
                      } catch (Exception xany) {
                          xcause = xany;
                      }
      
                  }
              }
      
              if (xcause == null) {
      
                 // resolve that property
      
                 List<PropertyResolver> resolvers = uberspect.getResolvers(operator, object);
                 JexlPropertyGet vg = uberspect.getPropertyGet(resolvers, object, attribute);
                 if (vg != null) {
                     try {
                         Object value = vg.invoke(object);
                         // cache executor in volatile JexlNode.value
                         if (node != null && cache && vg.isCacheable()) {
                             node.jjtSetValue(vg);
                         }
                         return value;
                     } catch (Exception xany) {
                         xcause = xany;
                     }
                 }
              }
              ...
      

      Attachments

        Activity

          People

            henrib Henri Biestro
            dmitri_blinov Dmitri Blinov
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: