Changeset 795:da47a9f8a7bb in livinglogic.java.ul4

Show
Ignore:
Timestamp:
02/05/13 16:30:03 (6 years ago)
Author:
Walter Doerwald <walter@…>
Branch:
default
Message:

Make sure that loop variables in list comps, dict comps and gen exprs don't leak.

Location:
src/main/java/com/livinglogic/ul4
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • src/main/java/com/livinglogic/ul4/DictComprehension.java

    r787 r795  
    6767        Iterator iter = Utils.iterator(container); 
    6868 
    69         while (iter.hasNext()) 
     69        // Store the loop variables into a local map, so they don't leak into the surrounding scope. 
     70        Map<String, Object> oldVariables = context.pushVariables(null); 
     71 
     72        try 
    7073        { 
    71             context.unpackVariable(varname, iter.next()); 
     74            while (iter.hasNext()) 
     75            { 
     76                context.unpackVariable(varname, iter.next()); 
    7277 
    73             if (condition == null || FunctionBool.call(condition.decoratedEvaluate(context))) 
    74             { 
    75                 Object key = this.key.decoratedEvaluate(context); 
    76                 Object value = this.value.decoratedEvaluate(context); 
    77                 result.put(key, value); 
     78                if (condition == null || FunctionBool.call(condition.decoratedEvaluate(context))) 
     79                { 
     80                    Object key = this.key.decoratedEvaluate(context); 
     81                    Object value = this.value.decoratedEvaluate(context); 
     82                    result.put(key, value); 
     83                } 
    7884            } 
     85        } 
     86        finally 
     87        { 
     88            context.setVariables(oldVariables); 
    7989        } 
    8090        return result; 
  • src/main/java/com/livinglogic/ul4/GeneratorExpression.java

    r787 r795  
    88 
    99import java.io.IOException; 
     10import java.util.Map; 
    1011import java.util.HashMap; 
    1112import java.util.LinkedList; 
     
    1617import com.livinglogic.ul4on.Decoder; 
    1718import com.livinglogic.ul4on.Encoder; 
     19 
     20import com.livinglogic.utils.MapChain; 
    1821 
    1922public class GeneratorExpression extends AST 
     
    8487        private Iterator iterator; 
    8588        private boolean hasNextItem; 
     89        private Map<String, Object> variables; 
    8690 
    8791        public GeneratorExpressionIterator(EvaluationContext context) 
     
    96100                throw new RuntimeException(ex); 
    97101            } 
     102            variables = new MapChain<String, Object>(new HashMap<String, Object>(), context.getVariables()); 
    98103            fetchNextItem(); 
    99104        } 
     
    101106        private void fetchNextItem() 
    102107        { 
    103             while (iterator.hasNext()) 
     108            Map<String, Object> oldVariables = context.setVariables(variables); 
     109            try 
    104110            { 
    105                 context.unpackVariable(varname, iterator.next()); 
    106                 boolean use; 
    107                 if (condition == null) 
    108                     use = true; 
    109                 else 
     111                while (iterator.hasNext()) 
    110112                { 
    111                     try 
     113                    context.unpackVariable(varname, iterator.next()); 
     114                    boolean use; 
     115                    if (condition == null) 
     116                        use = true; 
     117                    else 
    112118                    { 
    113                         use = FunctionBool.call(condition.decoratedEvaluate(context)); 
     119                        try 
     120                        { 
     121                            use = FunctionBool.call(condition.decoratedEvaluate(context)); 
     122                        } 
     123                        catch (IOException ex) 
     124                        { 
     125                            throw new RuntimeException(ex); 
     126                        } 
    114127                    } 
    115                     catch (IOException ex) 
     128                    if (use) 
    116129                    { 
    117                         throw new RuntimeException(ex); 
     130                        hasNextItem = true; 
     131                        return; 
    118132                    } 
    119133                } 
    120                 if (use) 
    121                 { 
    122                     hasNextItem = true; 
    123                     return; 
    124                 } 
     134                hasNextItem = false; 
    125135            } 
    126             hasNextItem = false; 
     136            finally 
     137            { 
     138                context.setVariables(oldVariables); 
     139            } 
    127140        } 
    128141 
     
    135148        { 
    136149            Object result; 
     150            Map<String, Object> oldVariables = context.setVariables(variables); 
    137151            try 
    138152            { 
     
    142156            { 
    143157                throw new RuntimeException(ex); 
     158            } 
     159            finally 
     160            { 
     161                context.setVariables(oldVariables); 
    144162            } 
    145163            fetchNextItem(); 
  • src/main/java/com/livinglogic/ul4/ListComprehension.java

    r787 r795  
    88 
    99import java.io.IOException; 
     10import java.util.Map; 
    1011import java.util.HashMap; 
    1112import java.util.LinkedList; 
     
    1617import com.livinglogic.ul4on.Decoder; 
    1718import com.livinglogic.ul4on.Encoder; 
     19 
     20import com.livinglogic.utils.MapChain; 
    1821 
    1922public class ListComprehension extends AST 
     
    6467        Iterator iter = Utils.iterator(container); 
    6568 
    66         while (iter.hasNext()) 
     69        // Store the loop variables into a local map, so they don't leak into the surrounding scope. 
     70        Map<String, Object> oldVariables = context.pushVariables(null); 
     71 
     72        try 
    6773        { 
    68             context.unpackVariable(varname, iter.next()); 
     74            while (iter.hasNext()) 
     75            { 
     76                context.unpackVariable(varname, iter.next()); 
    6977 
    70             if (condition == null || FunctionBool.call(condition.decoratedEvaluate(context))) 
    71             { 
    72                 Object item = this.item.decoratedEvaluate(context); 
    73                 result.add(item); 
     78                if (condition == null || FunctionBool.call(condition.decoratedEvaluate(context))) 
     79                { 
     80                    Object item = this.item.decoratedEvaluate(context); 
     81                    result.add(item); 
     82                } 
    7483            } 
     84        } 
     85        finally 
     86        { 
     87            context.setVariables(oldVariables); 
    7588        } 
    7689        return result;