Package dk.brics.string.intermediate

Examples of dk.brics.string.intermediate.Variable


  public Variable translateMethodCall(InstanceInvokeExpr expr,
      SootMethod target, Variable callee, List<Variable> arguments,
      IntermediateFactory factory) {
    for (MethodCallTranslator child : children) {
      Variable result = child.translateMethodCall(expr, target, callee, arguments, factory);
      if (result != null)
        return result;
    }
    return null;
  }
View Full Code Here


  }

  public Variable translateStaticMethodCall(InvokeExpr expr,
      List<Variable> arguments, IntermediateFactory factory) {
    for (MethodCallTranslator child : children) {
      Variable result = child.translateStaticMethodCall(expr, arguments, factory);
      if (result != null)
        return result;
    }
    return null;
  }
View Full Code Here

    // give up if no resolver could resolve the method
    if (resolution == null)
      return null;
   
    // make return value
    Variable result;
    if (resolution.getReturnedAutomaton() != null) {
      Automaton auto = resolution.getReturnedAutomaton();
     
      Variable temp = factory.createVariable(VariableType.STRING);
      factory.addStatement(new StringInit(temp, auto));
     
      switch (resultType) {
      case ARRAY:
        result = factory.createVariable(resultType);
View Full Code Here

        for (SootClass ac : getApplicationClasses()) {
            Method m = new Method(application, ac.getName() + ".toString",
                    new Variable[0]);
            methods.add(m);
            tostring_methods.put(ac.getName(), m);
            Variable var = application.createVariable(VariableType.STRING);
            StringStatement spot = new StringAssignment(var, var);
            m.addStatement(spot);
            Return ret = new Return(var);
            m.addStatement(ret);
            spot.addSucc(ret);
View Full Code Here

     */
    void makeBasicToStringMethod(Type prim, String classname, Automaton a) {
        Method m = new Method(application, classname + ".toString",
                new Variable[0]);
        SootClass c = Scene.v().getSootClass(classname);
        Variable var = application.createVariable(VariableType.STRING);
        StringStatement ss = new StringInit(var, a);
        m.addStatement(ss);
        m.getEntry().addSucc(ss);
        Return ret = new Return(var);
        m.addStatement(ret);
View Full Code Here

        // build the wrapper's body
        ControlFlowBuilder cfg = new ControlFlowBuilder(wrapper);
        cfg.moveToStatement(wrapper.getEntry());
       
        // create a variable holding any string
        Variable anyVar = application.createVariable(VariableType.STRING);
        Statement assignAny = new StringInit(anyVar, Basic.makeAnyString());
        cfg.addStatement(assignAny);

        // create a variable holding the null string
        Variable nullVar = application.createVariable(VariableType.STRING);
        Statement assignNull = new StringInit(nullVar, Automatons.getNull());
        cfg.addStatement(assignNull);
       
        // initialize externally visible field variables to anything
        // and set string fields to "null"
        for (SootClass ac : getApplicationClasses()) {
            for (SootField field : ac.getFields()) {
                // String fields should be assigned to "null" because they are
                // exempt from the
                // null-pointer analysis we use for other objects
                if (field.getType().equals(RefType.v("java.lang.String"))) {
                    FieldAssignment assignment = new FieldAssignment(
                            variableManager.getField(field), nullVar);
                    cfg.addStatement(assignment);
                }

                // corrupt externally visible fields
                if (ext.isExternallyVisibleField(field)) {
                    VariableType type = fromSootType(field
                            .getType());

                    if (type == VariableType.NONE)
                        continue;

                    Variable fieldInit;

                    switch (type) {
                    case OBJECT:
                    case STRING:
                    case PRIMITIVE:
                        fieldInit = anyVar;
                        break;

                    case STRINGBUFFER: {
                        fieldInit = application.createVariable(VariableType.STRINGBUFFER);
                        Statement s = new StringBufferCorrupt(fieldInit);
                        cfg.addStatement(s);
                        break;
                    }

                    case ARRAY: {
                        fieldInit = application.createVariable(VariableType.ARRAY);
                        Statement s = new ArrayCorrupt(fieldInit);
                        cfg.addStatement(s);
                        break;
                    }
                    default:
                        throw new RuntimeException("Unknown field type " + type);
                    }// switch

                    FieldAssignment assignment = new FieldAssignment(variableManager.getField(field), fieldInit);
                    cfg.addStatement(assignment);
                }
            }
        }
       
        // split control here, and call a random externally visible method
        cfg.startBranch();
       
        // call externally visible methods
        for (SootClass ac : getApplicationClasses()) {
            for (SootMethod sm : ac.getMethods()) {
                if (ext.isExternallyVisibleMethod(sm)) {
                    Method m = sms_m.get(sm.getSignature());
                    Variable[] params = m.getEntry().params;
                    Variable[] args = new Variable[params.length];
                    for (int i = 0; i < params.length; i++) {
                        Variable arg = application.createVariable(params[i].getType());
                        args[i] = arg;
                        Statement s;
                        switch (arg.getType()) {
                        case STRING:
                            s = new StringInit(arg, Basic.makeAnyString());
                            break;
                        case STRINGBUFFER:
                            s = new StringBufferCorrupt(arg);
                            break;
                        case ARRAY:
                            s = new ArrayCorrupt(arg);
                            break;
                        case PRIMITIVE:
                            // TODO: Integers can contain two characters, right? look deeper into which primitive type
                            s = new PrimitiveInit(arg, Automaton.makeAnyChar());
                            break;
                        default:
                            s = new ObjectCorrupt(arg);
                            // (case NONE or NULL cannot occur because such
                            // parameters do not get created for intermediate
                            // methods)
                        }
                        cfg.addStatement(s);
                    }
                    Variable retvar = makeVariable(sm.getReturnType());
                    Call c = new Call(retvar, m, args);
                    cfg.addStatement(c);
                    // If this is toString, remember the return value
                    if (sm.getName().equals("toString")
                            && sm.getParameterCount() == 0
View Full Code Here

        return false;
    }
    public Variable translateFieldRef(FieldRef reference, ValueBox box,
            IntermediateFactory factory) {
        for (FieldReferenceTranslator child : children) {
            Variable result = child.translateFieldRef(reference, box, factory);
            if (result != null)
                return result;
        }
        return null;
    }
View Full Code Here

   
    return translated;
  }

    public void addHotspot(Variable var, ValueBox box) {
        Variable hotspotValue = createVariable(var.getType());
        Hotspot hot = new Hotspot(hotspotValue, var);
        currentHotspots.add(new HotspotValueBoxPair(hot, box));
        addStatement(hot);
    }
View Full Code Here

                return callee;
               
            // String.concat(String)  [explicit, not invoked by + operator]
            } else if (methodName.equals("concat") && numArgs == 1 && isString(target.getParameterType(0))) {
                // translate the argument
                Variable rvar = arguments.get(0);
                Variable result = factory.createVariable(VariableType.STRING);
                factory.addStatement(new StringConcat(result, callee, rvar));
                return result;
               
            // String.replace(char,char)
            } else if (methodName.equals("replace") && numArgs == 2 &&
                    isChar(target.getParameterType(0)) &&
                    isChar(target.getParameterType(1))) {
                Integer arg1 = trackInteger(expr.getArg(0));
                Integer arg2 = trackInteger(expr.getArg(1));
                UnaryOperation op;
                if (arg1 != null) {
                    if (arg2 != null) {
                        op = new Replace1((char) arg1.intValue(), (char) arg2.intValue());
                    } else {
                        op = new Replace2((char) arg1.intValue());
                    }
                } else {
                    if (arg2 != null) {
                        op = new Replace3((char) arg2.intValue());
                    } else {
                        op = new Replace4();
                    }
                }
               
                Variable temp = factory.createVariable(VariableType.STRINGBUFFER);
                Variable result = factory.createVariable(VariableType.STRING);
                factory.addStatement(new StringBufferInit(temp, callee));
                factory.addStatement(new StringBufferUnaryOp(temp, op));
                factory.addStatement(new StringFromStringBuffer(result, temp));
                return result;
               
            // String.replace(CharSequence, CharSequence)
            } else if (methodName.equals("replace") && numArgs == 2 &&
                    isCharSequence(target.getParameterType(0)) &&
                    isCharSequence(target.getParameterType(1))) {
                String arg1 = trackString(expr.getArg(0));
                String arg2 = trackString(expr.getArg(1));
                Variable result = factory.createVariable(VariableType.STRING);
               
                // if either argument is unknown, give up.  [TODO make this better]
                if (arg1 == null || arg2 == null) {
                  factory.addStatement(new StringInit(result, Basic.makeAnyString()));
                  return result;
                }
               
                Replace6 rep = new Replace6(arg1, arg2);
                Variable temp = factory.createVariable(VariableType.STRINGBUFFER);
                factory.addStatement(new StringBufferInit(temp, callee));
                factory.addStatement(new StringBufferUnaryOp(temp, rep));
                factory.addStatement(new StringFromStringBuffer(result, temp));
                return result;
               
            // String.trim()
            } else if (methodName.equals("trim") && numArgs == 0) {
                UnaryOperation op = new Trim();
                Variable temp = factory.createVariable(VariableType.STRINGBUFFER);
                Variable result = factory.createVariable(VariableType.STRING);
                factory.addStatement(new StringBufferInit(temp, callee));
                factory.addStatement(new StringBufferUnaryOp(temp, op));
                factory.addStatement(new StringFromStringBuffer(result, temp));
                return result;
           
            // String.substring(int)    [this method returns a suffix of the string, starting at the specified index]
            } else if (methodName.equals("substring") && numArgs == 1) {
                UnaryOperation op = new Postfix();
                Variable temp = factory.createVariable(VariableType.STRINGBUFFER);
                Variable result = factory.createVariable(VariableType.STRING);
                factory.addStatement(new StringBufferInit(temp, callee));
                factory.addStatement(new StringBufferUnaryOp(temp, op));
                factory.addStatement(new StringFromStringBuffer(result, temp));
                return result;
           
            // String.substring(int,int)
            } else if (methodName.equals("substring") && numArgs == 2) {
                UnaryOperation op;
                Integer arg1 = trackInteger(expr.getArg(0));
                if (arg1 != null && arg1.intValue() == 0) {
                    op = new Prefix();
                } else {
                    op = new Substring();
                }
                Variable temp = factory.createVariable(VariableType.STRINGBUFFER);
                Variable result = factory.createVariable(VariableType.STRING);
                factory.addStatement(new StringBufferInit(temp, callee));
                factory.addStatement(new StringBufferUnaryOp(temp, op));
                factory.addStatement(new StringFromStringBuffer(result, temp));
                return result;
           
            // String.toLowerCase()
            } else if (methodName.equals("toLowerCase") && numArgs == 0) {
                UnaryOperation op = new ToLowerCase();
                Variable temp = factory.createVariable(VariableType.STRINGBUFFER);
                Variable result = factory.createVariable(VariableType.STRING);
                factory.addStatement(new StringBufferInit(temp, callee));
                factory.addStatement(new StringBufferUnaryOp(temp, op));
                factory.addStatement(new StringFromStringBuffer(result, temp));
                return result;
           
            // String.toUpperCase()
            } else if (methodName.equals("toUpperCase") && numArgs == 0) {
                UnaryOperation op = new ToUpperCase();
                Variable temp = factory.createVariable(VariableType.STRINGBUFFER);
                Variable result = factory.createVariable(VariableType.STRING);
                factory.addStatement(new StringBufferInit(temp, callee));
                factory.addStatement(new StringBufferUnaryOp(temp, op));
                factory.addStatement(new StringFromStringBuffer(result, temp));
                return result;
           
            // String.split(String)
            } else if (methodName.equals("split") && numArgs == 1) {
                Variable result = factory.createVariable(VariableType.ARRAY);
                factory.addStatement(new BasicUnaryOp(result, callee, new Split()));
                return result;
           
            // String.charAt(int)
            } else if (methodName.equals("charAt") && numArgs == 1) {
                UnaryOperation op;
                Integer arg = trackInteger(expr.getArg(0));
                if (arg != null) {
                    op = new CharAt1(arg);
                } else {
                    op = new CharAt2();
                }
                Variable result = factory.createVariable(VariableType.PRIMITIVE);
                factory.addStatement(new BasicUnaryOp(result, callee, op));
                return result;
               
            // String.contains(CharSequence)
            } else if (methodName.equals("contains") && numArgs == 1) {
                // this is experimental stuff. it is working, but probably not that useful
                Variable result = factory.createVariable(VariableType.PRIMITIVE);
                factory.addStatement(new BasicBinaryOp(result, callee, arguments.get(0), new Contains()));
                return result;
           
           
            // String.contentEquals(CharSequence) and String.contentEquals(StringBuffer)
            } else if (methodName.equals("contentEquals") && numArgs == 1) {
                // we can't say anything meaningful except the argument is NOT corrupted
                // (the argument will be considered corrupted if we do not handle it here)
                Variable result = factory.createVariable(VariableType.PRIMITIVE);
                factory.addStatement(new PrimitiveInit(result, Basic.getBinaryBooleans()));
                return result;
            }
           
            // String.toCharArray()
            else if (methodName.equals("toCharArray") && numArgs == 0) {
                Variable result = factory.createVariable(VariableType.ARRAY);
                factory.addStatement(new ArrayNew(result));
                Variable charAt = factory.createVariable(VariableType.PRIMITIVE);
                factory.addStatement(new BasicUnaryOp(charAt, callee, new CharAt2()));
                factory.addStatement(new ArrayWriteElement(result, charAt));
                return result;
            }
           
     
          return null;
     
    }
   
    //
    //    STRINGBUFFER
    //
    else if (isBufferOrBuilder(declaringClass)) {
      if (methodName.equals("toString") && numArgs == 0) {
        Variable result = factory.createVariable(VariableType.STRING);
                factory.addStatement(new StringFromStringBuffer(result, callee));
                return result;
            }
            // StringBuffer.append(<any type>)
            else if (methodName.equals("append") && numArgs == 1) {
                Variable rvar = valueOf(expr.getArgBox(0), arguments.get(0), 10, target.getParameterType(0), factory);
                factory.addStatement(new StringBufferAppend(callee, rvar));
                return callee;
            }
            // StringBuffer.insert(int, <any type>)
            else if (methodName.equals("insert") && numArgs == 2 &&
                    isInt(target.getParameterType(0))) {
                Integer pos = trackInteger(expr.getArg(0));
                Variable rvar = valueOf(expr.getArgBox(1), arguments.get(1), 10, target.getParameterType(0), factory);
                if (pos != null && pos.intValue() == 0) {
                  factory.addStatement(new StringBufferPrepend(callee, rvar));
                } else {
                  factory.addStatement(new StringBufferBinaryOp(callee, new Insert(), rvar));
                }
                return callee;
            }
            // StringBuffer.delete(int,int)
            else if (methodName.equals("delete") && numArgs == 2) {
                UnaryOperation op = new Delete();
                factory.addStatement(new StringBufferUnaryOp(callee, op));
                return callee;
            }
            // StringBuffer.deleteCharAt(int)
            else if (methodName.equals("deleteCharAt") && numArgs == 1) {
                UnaryOperation op = new DeleteCharAt();
                factory.addStatement(new StringBufferUnaryOp(callee, op));
                return callee;
            }
            // StringBuffer.replace(int start, int end, String replacement)
            else if (methodName.equals("replace") && numArgs == 3) {
                BinaryOperation op = new Replace5();
                Variable rvar = valueOf(expr.getArgBox(2), arguments.get(2), 10, target.getParameterType(2), factory);
                factory.addStatement(new StringBufferBinaryOp(callee, op, rvar));
                return callee;
            }
            // StringBuffer.reverse()
            else if (methodName.equals("reverse") && numArgs == 0) {
                UnaryOperation op = new Reverse();
                factory.addStatement(new StringBufferUnaryOp(callee, op));
                return callee;
            }
            // StringBuffer.setCharAt(int, char)  [NOTE: This method returns void]
            else if (methodName.equals("setCharAt") && numArgs == 2) {
                Integer c = trackInteger(expr.getArg(1));
                if (c == null) {
                    UnaryOperation op = new SetCharAt2();
                    factory.addStatement(new StringBufferUnaryOp(callee, op));
                } else {
                    UnaryOperation op = new SetCharAt1((char) c.intValue());
                    factory.addStatement(new StringBufferUnaryOp(callee, op));
                }
                return factory.getNothing();
            }
            // StringBuffer.setLength(int)      [NOTE: This method returns void]
            else if (methodName.equals("setLength") && numArgs == 1) {
                UnaryOperation op = new SetLength();
                factory.addStatement(new StringBufferUnaryOp(callee, op));
                return factory.getNothing();// returns void
            }
            // StringBuffer.substring(int)      [NOTE: Returns a string]
            else if (methodName.equals("substring") && numArgs == 1) {
                UnaryOperation op = new Postfix();

                Variable result = factory.createVariable(VariableType.STRING);
               
                // clone the stringbuffer
                Variable clone = makeStringBufferClone(callee, factory);
               
                // perform the substring operation on the clone
                factory.addStatement(new StringBufferUnaryOp(clone, op));
               
                // now put the clone's value back into the result variable
                factory.addStatement(new StringFromStringBuffer(result, clone));
               
                return result;
           
            // StringBuffer.substring(int,int)    [NOTE: Returns a string]
            else if (methodName.equals("substring") && numArgs == 2) {
                UnaryOperation op;
                Integer arg1 = trackInteger(expr.getArg(0));
                if (arg1 != null && arg1.intValue() == 0) {
                    op = new Prefix();
                } else {
                    op = new Substring();
                }
               
                Variable result = factory.createVariable(VariableType.STRING);
               
                // clone the stringbuffer
                Variable clone = makeStringBufferClone(callee, factory);
               
                // perform the substring operation on the clone
                factory.addStatement(new StringBufferUnaryOp(clone, op));
               
                // now put the clone's value back into the result variable
                factory.addStatement(new StringFromStringBuffer(result, clone));
               
                return result;
            }
     
            else if (STRING_BUFFER_IGNORED_METHODS_AUTO.run(methodName)) {
              // A method without side-effects. Just return something.
              return factory.createVariable(factory.fromSootType(target.getReturnType()));
            }
     
      System.err.println("Unknown StringBuffer method: " + target.getSignature());
    }
   
    //
    //  WRAPPERS
    //
    else if (isWrapperClass(declaringClass)) {
      if (methodName.equals("toString") && numArgs == 0) {
        Automaton typeAuto = Automatons.fromType(declaringClass.getName());
        if (typeAuto == null)
          throw new RuntimeException("Unknown wrapper class " + declaringClass.getName());
       
        Variable result = factory.createVariable(VariableType.STRING);
        factory.addStatement(new StringInit(result, typeAuto));
        return result;
      }
     
      //System.err.println("Unknown wrapper method: " + target.getSignature());
View Full Code Here

      // set(int,String)
      else if (methodName.equals("set") && numArgs == 2 && isInt(expr.getArg(0).getType()) && isString(expr.getArg(1).getType())) {
        // note: List.set returns the element previously at the position
       
        // get the old element
        Variable old = factory.createVariable(VariableType.STRING);
        factory.addStatement(new StringFromArray(old, callee));
       
        // insert the new element
        factory.addStatement(new ArrayWriteElement(callee, arguments.get(1)));
       
        return old;
      }
      // get(int)
      else if (methodName.equals("get") && numArgs == 1 && isInt(expr.getArg(0).getType())) {
        Variable result = factory.createVariable(VariableType.STRING);
        factory.addStatement(new StringFromArray(result, callee));
        return result;
      }
      // iterator()
      else if (methodName.equals("iterator") && numArgs == 0) {
        // changes to the collection might reflect on the iterator
        // and vice versa (eg using ListIterator.add)
        return callee;
      }
      // listIterator()
      else if (methodName.equals("listIterator") && numArgs == 0) {
        // changes to the collection might reflect on the iterator
        // and vice versa (eg using ListIterator.add)
        return callee;
      }
      // methods without side-effects returning booleans
      else if (methodName.equals("contains")
          || methodName.equals("containsAll")
          || methodName.equals("isEmpty")) {
        return anybool(factory);
      }
      // remove() and removeAll() are just identity operations for now
      else if (methodName.equals("remove")
          || methodName.equals("removeAll")) {
        return anybool(factory);
      }
      // size()
      else if (methodName.equals("size")) {
        return factory.getNothing();
      }
      else if (methodName.equals("toArray") && numArgs == 0) {
        Variable result = factory.createVariable(VariableType.ARRAY);
        factory.addStatement(new ArrayNew(result));
        factory.addStatement(new ArrayAddAll(result, callee));
        return result;
      }
      else if (methodName.equals("toArray") && numArgs == 1) {
        Variable result = factory.createVariable(VariableType.ARRAY);
       
        // the elements MIGHT be stored into the argument
        factory.startBranch();
        // 1) not stored in argument
        {
          factory.addStatement(new ArrayNew(result));
          factory.useBranch();
        }
        // 2) stored in argument
        {
          // note: existing elements in the array may remain
          // in particular if the array is larger than the collection,
          // the exceeding elements are unchanged, so do not clear the array here
          factory.addStatement(new ArrayAssignment(result, arguments.get(0)));
          factory.useBranch();
        }
        factory.endBranch();
       
        factory.addStatement(new ArrayAddAll(result, callee));
       
        return result;
      }
    }
   
    //
    // ITERATORS
    //
    else if (factory.isSubtypeOf(declaringClass, Scene.v().getSootClass("java.util.Iterator"))) {
      if (methodName.equals("hasNext") && numArgs == 0) {
        return anybool(factory); // no side-effects
      }
      else if (methodName.equals("hasPrevious") && numArgs == 0) {
        return anybool(factory); // no side-effects
      }
      else if ((methodName.equals("next") || methodName.equals("previous")) && numArgs == 0) {
        Variable result = factory.createVariable(VariableType.STRING);
        factory.addStatement(new StringFromArray(result, callee));
        return result;
      }
      else if (methodName.equals("remove") && numArgs == 1) {
        return anybool(factory); // just prevent corruption
View Full Code Here

TOP

Related Classes of dk.brics.string.intermediate.Variable

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.