Commits

Anonymous committed 62f6520

Fixes for OGNL-130. Two dimensional List access was improperly stealing pre-cast statements from ASTProperty children.

  • Participants
  • Parent commits 5411ee4

Comments (0)

Files changed (11)

File src/java/ognl/ASTChain.java

 
     private Class _getterClass;
     private Class _setterClass;
-    
+
     private String _lastExpression;
-    
+
     private String _coreExpression;
-    
+
     public ASTChain(int id)
     {
         super(id);
     {
         super(p, id);
     }
-    
+
     public String getLastExpression()
     {
         return _lastExpression;
     }
-    
+
     public String getCoreExpression()
     {
         return _coreExpression;
     }
-    
+
     public void jjtClose()
     {
         flattenTree();
     }
 
     protected Object getValueBody(OgnlContext context, Object source)
-        throws OgnlException
+            throws OgnlException
     {
         Object result = source;
 
 
                     if ((indexType != OgnlRuntime.INDEXED_PROPERTY_NONE) && (_children[i + 1] instanceof ASTProperty)) {
                         ASTProperty indexNode = (ASTProperty) _children[i + 1];
-                        
+
                         if (indexNode.isIndexedAccess()) {
                             Object index = indexNode.getProperty(context, result);
 
                                     int len = Array.getLength(array);
 
                                     switch(((DynamicSubscript) index).getFlag()) {
-                                    case DynamicSubscript.ALL:
-                                        result = Array.newInstance(array.getClass().getComponentType(), len);
-                                        System.arraycopy(array, 0, result, 0, len);
-                                        handled = true;
-                                        i++;
-                                        break;
-                                    case DynamicSubscript.FIRST:
-                                        index = new Integer((len > 0) ? 0 : -1);
-                                        break;
-                                    case DynamicSubscript.MID:
-                                        index = new Integer((len > 0) ? (len / 2) : -1);
-                                        break;
-                                    case DynamicSubscript.LAST:
-                                        index = new Integer((len > 0) ? (len - 1) : -1);
-                                        break;
+                                        case DynamicSubscript.ALL:
+                                            result = Array.newInstance(array.getClass().getComponentType(), len);
+                                            System.arraycopy(array, 0, result, 0, len);
+                                            handled = true;
+                                            i++;
+                                            break;
+                                        case DynamicSubscript.FIRST:
+                                            index = new Integer((len > 0) ? 0 : -1);
+                                            break;
+                                        case DynamicSubscript.MID:
+                                            index = new Integer((len > 0) ? (len / 2) : -1);
+                                            break;
+                                        case DynamicSubscript.LAST:
+                                            index = new Integer((len > 0) ? (len - 1) : -1);
+                                            break;
                                     }
                                 } else {
                                     if (indexType == OgnlRuntime.INDEXED_PROPERTY_OBJECT) { throw new OgnlException(
                                             "DynamicSubscript '" + indexNode
-                                                    + "' not allowed for object indexed property '" + propertyNode
-                                                    + "'"); }
+                                            + "' not allowed for object indexed property '" + propertyNode
+                                            + "'"); }
                                 }
                             }
                             if (!handled) {
     }
 
     protected void setValueBody(OgnlContext context, Object target, Object value)
-        throws OgnlException
+            throws OgnlException
     {
         boolean handled = false;
 
                                     int len = Array.getLength(array);
 
                                     switch(((DynamicSubscript) index).getFlag()) {
-                                    case DynamicSubscript.ALL:
-                                        System.arraycopy(target, 0, value, 0, len);
-                                        handled = true;
-                                        i++;
-                                        break;
-                                    case DynamicSubscript.FIRST:
-                                        index = new Integer((len > 0) ? 0 : -1);
-                                        break;
-                                    case DynamicSubscript.MID:
-                                        index = new Integer((len > 0) ? (len / 2) : -1);
-                                        break;
-                                    case DynamicSubscript.LAST:
-                                        index = new Integer((len > 0) ? (len - 1) : -1);
-                                        break;
+                                        case DynamicSubscript.ALL:
+                                            System.arraycopy(target, 0, value, 0, len);
+                                            handled = true;
+                                            i++;
+                                            break;
+                                        case DynamicSubscript.FIRST:
+                                            index = new Integer((len > 0) ? 0 : -1);
+                                            break;
+                                        case DynamicSubscript.MID:
+                                            index = new Integer((len > 0) ? (len / 2) : -1);
+                                            break;
+                                        case DynamicSubscript.LAST:
+                                            index = new Integer((len > 0) ? (len - 1) : -1);
+                                            break;
                                     }
                                 } else {
                                     if (indexType == OgnlRuntime.INDEXED_PROPERTY_OBJECT) { throw new OgnlException(
                                             "DynamicSubscript '" + indexNode
-                                                    + "' not allowed for object indexed property '" + propertyNode
-                                                    + "'"); }
+                                            + "' not allowed for object indexed property '" + propertyNode
+                                            + "'"); }
                                 }
                             }
                             if (!handled) {
                                 OgnlRuntime.setIndexedProperty(context, target, propertyNode.getProperty(context,
-                                        target).toString(), index, value);
+                                                                                                         target).toString(), index, value);
                                 handled = true;
                                 i++;
                             }
     }
 
     public boolean isSimpleNavigationChain(OgnlContext context)
-        throws OgnlException
+            throws OgnlException
     {
         boolean result = false;
-        
+
         if ((_children != null) && (_children.length > 0)) {
             result = true;
             for(int i = 0; result && (i < _children.length); i++) {
     {
         return _getterClass;
     }
-    
+
     public Class getSetterClass()
     {
         return _setterClass;
     }
-    
+
     public String toString()
     {
         String result = "";
         }
         return result;
     }
-    
+
     public String toGetSourceString(OgnlContext context, Object target)
     {
         String prevChain = (String)context.get("_currentChain");
-        
-        if (target != null) {
+
+        if (target != null)
+        {
             context.setCurrentObject(target);
             context.setCurrentType(target.getClass());
         }
-        
+
         String result = "";
         NodeType _lastType = null;
         boolean ordered = false;
         boolean constructor = false;
         try {
-            if ((_children != null) && (_children.length > 0)) {
-                for(int i = 0; i < _children.length; i++) {
-                    
-                     /*System.out.println("astchain child: " + _children[i].getClass().getName()
+            if ((_children != null) && (_children.length > 0))
+            {
+                for(int i = 0; i < _children.length; i++)
+                {
+                    /* System.out.println("astchain child: " + _children[i].getClass().getName()
                                        + " with current object target " + context.getCurrentObject()
-                                       + " current type: " + context.getCurrentType());*/
+                                       + " current type: " + context.getCurrentType()); */
 
                     String value = _children[i].toGetSourceString(context, context.getCurrentObject());
-                    
+
 //                    System.out.println("astchain child returned >>  " + value + "  <<");
-                    
+
                     if (ASTCtor.class.isInstance(_children[i]))
                         constructor = true;
-                    
-                    if (NodeType.class.isInstance(_children[i]) 
-                            && ((NodeType)_children[i]).getGetterClass() != null) {
-                        
+
+                    if (NodeType.class.isInstance(_children[i])
+                        && ((NodeType)_children[i]).getGetterClass() != null)
+                    {
                         _lastType = (NodeType)_children[i];
                     }
 
 //                    System.out.println("Astchain i: " + i + " currentobj : " + context.getCurrentObject() + " and root: " + context.getRoot());
-                    if (!ASTVarRef.class.isInstance(_children[i]) && !constructor && !(OrderedReturn.class.isInstance(_children[i]) && ((OrderedReturn)_children[i]).getLastExpression() != null)
-                            && (_parent == null || !ASTSequence.class.isInstance(_parent))) {
+                    if (!ASTVarRef.class.isInstance(_children[i]) && !constructor
+                        && !(OrderedReturn.class.isInstance(_children[i]) && ((OrderedReturn)_children[i]).getLastExpression() != null)
+                        && (_parent == null || !ASTSequence.class.isInstance(_parent)))
+                    {
+                        value = OgnlRuntime.getCompiler().castExpression(context, _children[i], value);
+                    }
+
+                    /* System.out.println("astchain value now : " + value + " with index " + i
+                                       + " current type " + context.getCurrentType() + " current accessor " + context.getCurrentAccessor()
+                                       + " prev type " + context.getPreviousType() + " prev accessor " + context.getPreviousAccessor()); */
+
+                    if (OrderedReturn.class.isInstance(_children[i]) && ((OrderedReturn)_children[i]).getLastExpression() != null)
+                    {
+                        ordered = true;
+                        OrderedReturn or = (OrderedReturn)_children[i];
+
+                        if (or.getCoreExpression() == null || or.getCoreExpression().trim().length() <= 0)
+                            result = "";
+                        else
+                            result += or.getCoreExpression();
+
+                        _lastExpression = or.getLastExpression();
+
+                        if (context.get(ExpressionCompiler.PRE_CAST) != null)
+                        {
+                            _lastExpression = context.remove(ExpressionCompiler.PRE_CAST) + _lastExpression;
+                        }
+                    } else if (ASTOr.class.isInstance(_children[i])
+                               || ASTAnd.class.isInstance(_children[i])
+                               || ASTCtor.class.isInstance(_children[i])
+                               || (ASTStaticField.class.isInstance(_children[i]) && _parent == null))
+                    {
+                        context.put("_noRoot", "true");
+                        result = value;
+                    } else
+                    {
+                        result += value;
+                    }
+
+                    context.put("_currentChain", result);
+                }
+            }
+        } catch (Throwable t)
+        {
+            throw OgnlOps.castToRuntime(t);
+        }
+
+        if (_lastType != null) {
+            _getterClass = _lastType.getGetterClass();
+            _setterClass = _lastType.getSetterClass();
+        }
+
+        if (ordered) {
+            _coreExpression = result;
+        }
+
+        context.put("_currentChain", prevChain);
+
+        return result;
+    }
+
+    public String toSetSourceString(OgnlContext context, Object target)
+    {
+        String prevChain = (String)context.get("_currentChain");
+        String prevChild = (String)context.get("_lastChild");
+
+        if (prevChain != null)
+            throw new UnsupportedCompilationException("Can't compile nested chain expressions.");
+
+        if (target != null) {
+            context.setCurrentObject(target);
+            context.setCurrentType(target.getClass());
+        }
+
+        String result = "";
+        NodeType _lastType = null;
+        boolean constructor = false;
+        try {
+            if ((_children != null) && (_children.length > 0)) {
+                for(int i = 0; i < _children.length; i++) {
+                    // System.out.println("astchain setsource child : " + _children[i].getClass().getName());
+
+                    if (i == (_children.length -1)) {
+
+                        context.put("_lastChild", "true");
+                    }
+
+                    String value = _children[i].toSetSourceString(context, context.getCurrentObject());
+                    if (value == null || value.trim().length() <= 0)
+                        return "";
+
+                    if (ASTCtor.class.isInstance(_children[i]))
+                        constructor = true;
+
+                    if (NodeType.class.isInstance(_children[i])
+                        && ((NodeType)_children[i]).getGetterClass() != null) {
+
+                        _lastType = (NodeType)_children[i];
+                    }
+
+                    if (!constructor && !OrderedReturn.class.isInstance(_children[i])
+                        && (_parent == null || !ASTSequence.class.isInstance(_parent))) {
 
                         value = OgnlRuntime.getCompiler().castExpression(context, _children[i], value);
                     }
 
-                    /*System.out.println("astchain value now : " + value + " with index " + i
-                    + " current type " + context.getCurrentType() + " current accessor " + context.getCurrentAccessor()
-                    + " prev type " + context.getPreviousType() + " prev accessor " + context.getPreviousAccessor());*/
-
-                    if (OrderedReturn.class.isInstance(_children[i]) && ((OrderedReturn)_children[i]).getLastExpression() != null) {
-                        
-                        ordered = true;
-                        OrderedReturn or = (OrderedReturn)_children[i];
-                        
-                        if (or.getCoreExpression() == null || or.getCoreExpression().trim().length() <= 0)
-                            result = "";
-                        else
-                            result += or.getCoreExpression();
-                        
-                        _lastExpression = or.getLastExpression();
-                        
-                        if (context.get(ExpressionCompiler.PRE_CAST) != null) {
-                            _lastExpression = context.remove(ExpressionCompiler.PRE_CAST) + _lastExpression;
-                        }
-                    } else if (ASTOr.class.isInstance(_children[i])
-                            || ASTAnd.class.isInstance(_children[i])
-                            || ASTCtor.class.isInstance(_children[i])
-                            || (ASTStaticField.class.isInstance(_children[i]) && _parent == null)) {
+                    if (ASTOr.class.isInstance(_children[i])
+                        || ASTAnd.class.isInstance(_children[i])
+                        || ASTCtor.class.isInstance(_children[i])
+                        || ASTStaticField.class.isInstance(_children[i])) {
                         context.put("_noRoot", "true");
                         result = value;
                     } else
         {
             throw OgnlOps.castToRuntime(t);
         }
-        
-        if (_lastType != null) {
-            _getterClass = _lastType.getGetterClass();
-            _setterClass = _lastType.getSetterClass();
-        }
-        
-        if (ordered) {
-            _coreExpression = result;
-        }
-        
-        context.put("_currentChain", prevChain);
-        
-        return result;
-    }
-    
-    public String toSetSourceString(OgnlContext context, Object target)
-    {
-        String prevChain = (String)context.get("_currentChain");
-        String prevChild = (String)context.get("_lastChild");
-        
-        if (prevChain != null)
-            throw new UnsupportedCompilationException("Can't compile nested chain expressions.");
-        
-        if (target != null) {
-            context.setCurrentObject(target);
-            context.setCurrentType(target.getClass());
-        }
 
-        String result = "";
-        NodeType _lastType = null;
-        boolean constructor = false;
-        try {
-            if ((_children != null) && (_children.length > 0)) {
-                for(int i = 0; i < _children.length; i++) {
-                    // System.out.println("astchain setsource child : " + _children[i].getClass().getName());
-                    
-                    if (i == (_children.length -1)) {
-                        
-                        context.put("_lastChild", "true");
-                    }
-                    
-                    String value = _children[i].toSetSourceString(context, context.getCurrentObject());
-                    if (value == null || value.trim().length() <= 0)
-                        return "";
-                    
-                    if (ASTCtor.class.isInstance(_children[i]))
-                        constructor = true;
-                    
-                    if (NodeType.class.isInstance(_children[i]) 
-                            && ((NodeType)_children[i]).getGetterClass() != null) {
-                        
-                        _lastType = (NodeType)_children[i];
-                    }
-                    
-                    if (!constructor && !OrderedReturn.class.isInstance(_children[i]) 
-                            && (_parent == null || !ASTSequence.class.isInstance(_parent))) {
-                        
-                        value = OgnlRuntime.getCompiler().castExpression(context, _children[i], value);
-                    }
-                    
-                    if (ASTOr.class.isInstance(_children[i])
-                            || ASTAnd.class.isInstance(_children[i])
-                            || ASTCtor.class.isInstance(_children[i])
-                            || ASTStaticField.class.isInstance(_children[i])) {
-                        context.put("_noRoot", "true");
-                        result = value;
-                    } else
-                        result += value;
-                    
-                    context.put("_currentChain", result);
-                }
-            }
-        } catch (Throwable t)
-        {
-            throw OgnlOps.castToRuntime(t);
-        }
-        
         context.put("_lastChild", prevChild);
         context.put("_currentChain", prevChain);
-        
+
         if (_lastType != null)
             _setterClass = _lastType.getSetterClass();
-        
+
         return result;
     }
 }

File src/java/ognl/ASTConst.java

     public String toGetSourceString(OgnlContext context, Object target)
     {
         if (value == null && _parent != null && ExpressionNode.class.isInstance(_parent))
+        {
+            context.setCurrentType(null);
             return "null";
-        else if (value == null)
+        } else if (value == null)
+        {
+            context.setCurrentType(null);
             return "";
+        }
         
         _getterClass = value.getClass();
 

File src/java/ognl/ASTProperty.java

         Method m = null;
 
         try {
-            /*System.out.println("astproperty is indexed? : " + isIndexedAccess() + " child: " + _children[0].getClass().getName()
+            /* System.out.println("astproperty is indexed? : " + isIndexedAccess() + " child: " + _children[0].getClass().getName()
                                + " target: " + target.getClass().getName() + " current object: " + context.getCurrentObject().getClass().getName());*/
 
             if (isIndexedAccess())
                 String srcString = _children[0].toGetSourceString(context, context.getRoot());
                 srcString = ExpressionCompiler.getRootExpression(_children[0], context.getRoot(), context) + srcString;
 
-                if (!ASTConst.class.isInstance(_children[0]))
+                //if (!ASTConst.class.isInstance(_children[0]) && !ASTProperty.class.isInstance(_children[0]))
+                if (ASTChain.class.isInstance(_children[0]))
                 {
                     String cast = (String)context.remove(ExpressionCompiler.PRE_CAST);
                     if (cast != null)

File src/java/ognl/ObjectPropertyAccessor.java

 
                 return "";
             }
-
+            
             context.setCurrentType(m.getReturnType());
             context.setCurrentAccessor(OgnlRuntime.getCompiler().getSuperOrInterfaceClass(m, m.getDeclaringClass()));
 

File src/test/java/org/ognl/test/IndexAccessTest.java

             {ROOT, "list[size() - 1]", MethodFailedException.class},
             {ROOT, "(index == (array.length - 3)) ? 'toggle toggleSelected' : 'toggle'", "toggle toggleSelected"},
             {ROOT, "\"return toggleDisplay('excdisplay\"+index+\"', this)\"", "return toggleDisplay('excdisplay1', this)"},
-            {ROOT, "map[mapKey].split('=')[0]", "StringStuff"}
+            {ROOT, "map[mapKey].split('=')[0]", "StringStuff"},
+            {ROOT, "booleanValues[index1][index2]", Boolean.FALSE}
     };
 
     /*

File src/test/java/org/ognl/test/MethodTest.java

 
     private static Simple ROOT = new Simple();
     private static ListSource LIST = new ListSourceImpl();
-    private static BaseGeneric GENERIC = new GameGeneric();
+    private static BaseGeneric<GameGenericObject> GENERIC = new GameGeneric();
 
     private static Object[][] TESTS = {
             { "hashCode()", new Integer(ROOT.hashCode()) } ,
             { LIST, "addValue(name)", Boolean.TRUE},
             { "getDisplayValue(methodsTest.allowDisplay)", "test"},
             { "isThisVarArgsWorking(three, rootValue)", Boolean.TRUE},
-            { GENERIC, "message + ' ' + service.getFullMessageFor(value, null)", "Message Halo 3"}
+            { GENERIC, "service.getFullMessageFor(value, null)", "Halo 3"}
     };
 
     public static class A

File src/test/java/org/ognl/test/objects/BaseGeneric.java

     {
         return _service;
     }
+
+    public String format(Object value)
+    {
+        return value.toString();
+    }
 }

File src/test/java/org/ognl/test/objects/GameGenericObject.java

     {
         return "Halo 3";
     }
+
+    public String getHappy()
+    {
+        return "happy";
+    }
 }

File src/test/java/org/ognl/test/objects/GenericService.java

 
     String getFullMessageFor(PersonGenericObject person, Object...arguments);
 
-    String getFullMessageFor(GameGenericObject game, Object...arguments);
+    String getFullMessageFor(GameGenericObject game, Object...arguments);    
 }

File src/test/java/org/ognl/test/objects/GenericServiceImpl.java

  */
 public class GenericServiceImpl implements GenericService {
 
+    public String getFullMessageFor(GameGenericObject game, Object... arguments)
+    {
+        game.getHappy();
+        
+        return game.getDisplayName();
+    }
+
     public String getFullMessageFor(PersonGenericObject person, Object... arguments)
     {
         return person.getDisplayName();
     }
-
-    public String getFullMessageFor(GameGenericObject game, Object... arguments)
-    {
-        return game.getDisplayName();
-    }
 }

File src/test/java/org/ognl/test/objects/Root.java

     public int                      six = 6;
     private boolean _disabled;
     private Locale _selected = Locale.getDefault();
+    private List<List<Boolean>> _booleanValues = new ArrayList<List<Boolean>>();
 
     private boolean[] _booleanArray = {true, false, true, true};
     private List _list;
 
         /* make myMap identical */
         myMap.putAll( map );
+
+        List<Boolean> bool1 = new ArrayList<Boolean>();
+        bool1.add(Boolean.TRUE);
+        bool1.add(Boolean.FALSE);
+        bool1.add(Boolean.TRUE);
+
+        _booleanValues.add(bool1);
+
+        List<Boolean> bool2 = new ArrayList<Boolean>();
+        bool2.add(Boolean.TRUE);
+        bool2.add(Boolean.FALSE);
+        bool2.add(Boolean.TRUE);
+
+        _booleanValues.add(bool2);
     }
 
     private boolean isPrivateAccessorBooleanValue()
         return true;
     }
 
+    public List<List<Boolean>> getBooleanValues()
+    {
+        return _booleanValues;
+    }
+
+    public int getIndex1()
+    {
+        return 1;
+    }
+
+    public int getIndex2()
+    {
+        return 1;
+    }
+
     public static class A
     {
         public int methodOfA(B b)