Beispiel #1
0
 /** 11.2.1 assignment with left-hand-side property accessor. */
 @Override
 public void visit(WritePropertyNode n, State state) {
   // get the base value, coerce with ToObject
   Value baseval = state.readRegister(n.getBaseRegister());
   baseval = UnknownValueResolver.getRealValue(baseval, state);
   m.visitPropertyAccess(n, baseval);
   Set<ObjectLabel> objlabels = Conversion.toObjectLabels(state, n, baseval, c);
   if (objlabels.isEmpty() && !Options.get().isPropagateDeadFlow()) {
     state.setToNone();
     return;
   }
   state.writeRegister(
       n.getBaseRegister(),
       Value.makeObject(objlabels)); // if null/undefined, an exception would have been thrown via
   // toObjectLabels
   // get the property name value, separate the undefined/null/NaN components, coerce with ToString
   Value propertyval;
   int propertyreg;
   if (n.isPropertyFixed()) {
     propertyreg = AbstractNode.NO_VALUE;
     propertyval = Value.makeStr(n.getPropertyString());
   } else {
     propertyreg = n.getPropertyRegister();
     propertyval = state.readRegister(propertyreg);
     propertyval = UnknownValueResolver.getRealValue(propertyval, state);
   }
   boolean maybe_undef = propertyval.isMaybeUndef();
   boolean maybe_null = propertyval.isMaybeNull();
   boolean maybe_nan = propertyval.isMaybeNaN();
   propertyval = propertyval.restrictToNotNullNotUndef().restrictToNotNaN();
   Str propertystr = Conversion.toString(propertyval, propertyreg, c);
   // get the value to be written
   Value v = state.readRegister(n.getValueRegister());
   NativeFunctions.updateArrayLength(n, state, objlabels, propertystr, v, n.getValueRegister(), c);
   // write the object property value, as fixed property name or unknown property name, and
   // separately for "undefined"/"null"/"NaN"
   state.writeProperty(objlabels, propertystr, v, true, maybe_undef || maybe_null || maybe_nan);
   if (maybe_undef && !propertystr.isMaybeStr("undefined"))
     state.writeProperty(
         objlabels, Value.makeTemporaryStr("undefined"), v, true, !propertystr.isNotStr());
   if (maybe_null && !propertystr.isMaybeStr("null"))
     state.writeProperty(
         objlabels, Value.makeTemporaryStr("null"), v, true, !propertystr.isNotStr());
   if (maybe_nan && !propertystr.isMaybeStr("NaN"))
     state.writeProperty(
         objlabels, Value.makeTemporaryStr("NaN"), v, true, !propertystr.isNotStr());
   m.visitPropertyWrite(n, objlabels, propertystr); // TODO: more monitoring around here?
   if (Options.get().isEvalStatistics()
       && propertystr.getStr() != null
       && propertystr.getStr().equals("innerHTML")) {
     m.visitInnerHTMLWrite(n, v);
   }
   m.visitVariableOrProperty(
       n.getPropertyString(), n.getSourceLocation(), v, state.getContext(), state);
 }
Beispiel #2
0
 /** Transfer Functions. */
 public static Value evaluate(DOMObjects nativeObject, CallInfo call, Solver.SolverInterface c) {
   State s = c.getState();
   switch (nativeObject) {
     case ELEMENT_GET_ATTRIBUTE:
       {
         NativeFunctions.expectParameters(nativeObject, call, c, 1, 1);
         /* Value name =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 0), c);
         return Value.makeAnyStr();
       }
     case ELEMENT_SET_ATTRIBUTE:
       {
         NativeFunctions.expectParameters(nativeObject, call, c, 2, 2);
         /* Value name =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 0), c);
         /* Value value =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 1), c);
         return Value.makeUndef();
       }
     case ELEMENT_REMOVE_ATTRIBUTE:
       {
         NativeFunctions.expectParameters(nativeObject, call, c, 1, 1);
         /* Value name =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 0), c);
         return Value.makeUndef();
       }
     case ELEMENT_GET_ATTRIBUTE_NS:
       {
         NativeFunctions.expectParameters(nativeObject, call, c, 2, 2);
         /* Value namespace =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 0), c);
         /* Value name =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 1), c);
         return Value.makeAnyStr();
       }
     case ELEMENT_GET_ATTRIBUTE_NODE:
       {
         NativeFunctions.expectParameters(nativeObject, call, c, 1, 1);
         /* Value name =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 0), c);
         return Value.makeObject(DOMAttr.INSTANCES);
       }
     case ELEMENT_GET_ATTRIBUTE_NODE_NS:
       {
         NativeFunctions.expectParameters(nativeObject, call, c, 2, 2);
         /* Value namespace =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 0), c);
         /* Value name =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 1), c);
         return Value.makeObject(DOMAttr.INSTANCES);
       }
     case ELEMENT_GET_BOUNDING_CLIENT_RECT:
       {
         NativeFunctions.expectParameters(nativeObject, call, c, 0, 0);
         return Value.makeObject(ClientBoundingRect.INSTANCES);
       }
     case ELEMENT_GET_ELEMENTS_BY_TAGNAME:
       {
         // TODO: needs precision, but cannot do like document.getElementsByTagName() bc. State is
         // for everything
         NativeFunctions.expectParameters(nativeObject, call, c, 1, 1);
         /* Value name =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 0), c);
         return Value.makeObject(DOMNodeList.INSTANCES);
       }
     case ELEMENT_GET_ELEMENTS_BY_TAGNAME_NS:
       {
         NativeFunctions.expectParameters(nativeObject, call, c, 2, 2);
         /* Value namespace =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 0), c);
         /* Value name =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 1), c);
         return Value.makeObject(DOMNodeList.INSTANCES);
       }
     case ELEMENT_HAS_ATTRIBUTE:
       {
         NativeFunctions.expectParameters(nativeObject, call, c, 1, 1);
         /* Value name =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 0), c);
         return Value.makeAnyBool();
       }
     case ELEMENT_HAS_ATTRIBUTE_NS:
       {
         NativeFunctions.expectParameters(nativeObject, call, c, 2, 2);
         /* Value namespace =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 0), c);
         /* Value name =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 1), c);
         return Value.makeAnyBool();
       }
     case ELEMENT_REMOVE_ATTRIBUTE_NS:
       {
         NativeFunctions.expectParameters(nativeObject, call, c, 2, 2);
         /* Value namespaceURI =*/ Conversion.toString(
             NativeFunctions.readParameter(call, s, 0), c);
         /* Value localName =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 1), c);
         return Value.makeUndef();
       }
     case ELEMENT_REMOVE_ATTRIBUTE_NODE:
       {
         NativeFunctions.expectParameters(nativeObject, call, c, 1, 1);
         return DOMConversion.toAttr(NativeFunctions.readParameter(call, s, 0), c);
       }
     case ELEMENT_SET_ATTRIBUTE_NS:
       {
         NativeFunctions.expectParameters(nativeObject, call, c, 3, 3);
         /* Value namespace =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 0), c)
             .joinNull();
         /* Value name =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 1), c);
         /* Value value =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 2), c);
         return Value.makeUndef();
       }
     case ELEMENT_SET_ATTRIBUTE_NODE:
       {
         NativeFunctions.expectParameters(nativeObject, call, c, 1, 1);
         /* Value newAttr =*/ DOMConversion.toAttr(NativeFunctions.readParameter(call, s, 0), c);
         return Value.makeObject(DOMAttr.INSTANCES).joinNull();
       }
     case ELEMENT_SET_ATTRIBUTE_NODE_NS:
       {
         NativeFunctions.expectParameters(nativeObject, call, c, 1, 1);
         /* Value newAttr =*/ DOMConversion.toAttr(NativeFunctions.readParameter(call, s, 0), c);
         return Value.makeObject(DOMAttr.INSTANCES).joinNull();
       }
     case ELEMENT_SET_ID_ATTRIBUTE:
       {
         NativeFunctions.expectParameters(nativeObject, call, c, 2, 2);
         /* Value name =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 0), c);
         /* Value isId =*/ Conversion.toBoolean(NativeFunctions.readParameter(call, s, 1));
         return Value.makeUndef();
       }
     case ELEMENT_SET_ID_ATTRIBUTE_NS:
       {
         NativeFunctions.expectParameters(nativeObject, call, c, 3, 3);
         /* Value namespaceURI =*/ Conversion.toString(
             NativeFunctions.readParameter(call, s, 0), c);
         /* Value localName =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 1), c);
         /* Value isId =*/ Conversion.toBoolean(NativeFunctions.readParameter(call, s, 2));
         return Value.makeUndef();
       }
     case ELEMENT_SET_ID_ATTRIBUTE_NODE:
       {
         NativeFunctions.expectParameters(nativeObject, call, c, 2, 2);
         /* Value idAttr =*/ DOMConversion.toAttr(NativeFunctions.readParameter(call, s, 0), c);
         /* Value isId =*/ Conversion.toBoolean(NativeFunctions.readParameter(call, s, 1));
         return Value.makeUndef();
       }
     case ELEMENT_QUERY_SELECTOR_ALL:
       {
         NativeFunctions.expectParameters(nativeObject, call, c, 1, 1);
         return Value.makeObject(DOMNodeList.INSTANCES);
       }
     default:
       {
         throw new AnalysisException("Unknown Native Object: " + nativeObject);
       }
   }
 }
Beispiel #3
0
 public static Value evaluate(
     DOMObjects nativeObject, FunctionCalls.CallInfo call, State s, Solver.SolverInterface c) {
   switch (nativeObject) {
     case MOUSE_EVENT_INIT_MOUSE_EVENT:
       {
         NativeFunctions.expectParameters(nativeObject, call, c, 15, 15);
         /* Value typeArg =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 0), c);
         /* Value canBubbleArg =*/ Conversion.toBoolean(NativeFunctions.readParameter(call, s, 1));
         /* Value cancelableArg =*/ Conversion.toBoolean(
             NativeFunctions.readParameter(call, s, 2));
         // View arg not checked
         /* Value detailArg =*/ Conversion.toNumber(NativeFunctions.readParameter(call, s, 4), c);
         /* Value screenXArg =*/ Conversion.toNumber(NativeFunctions.readParameter(call, s, 5), c);
         /* Value screenYArg =*/ Conversion.toNumber(NativeFunctions.readParameter(call, s, 6), c);
         /* Value clientXArg =*/ Conversion.toNumber(NativeFunctions.readParameter(call, s, 7), c);
         /* Value clientYArg =*/ Conversion.toNumber(NativeFunctions.readParameter(call, s, 8), c);
         /* Value ctrlKeyArg =*/ Conversion.toBoolean(NativeFunctions.readParameter(call, s, 9));
         /* Value altKeyArg =*/ Conversion.toBoolean(NativeFunctions.readParameter(call, s, 10));
         /* Value shiftKeyArg =*/ Conversion.toBoolean(NativeFunctions.readParameter(call, s, 11));
         /* Value metaKeyArg =*/ Conversion.toBoolean(NativeFunctions.readParameter(call, s, 12));
         /* Value buttonArg =*/ Conversion.toNumber(NativeFunctions.readParameter(call, s, 13), c);
         /* Value relatedTargetArg =*/ DOMConversion.toEventTarget(
             NativeFunctions.readParameter(call, s, 14), c);
         return Value.makeUndef();
       }
     default:
       throw new UnsupportedOperationException("Unsupported Native Object: " + nativeObject);
   }
 }
Beispiel #4
0
  /** Evaluates the given native function. */
  public static Value evaluate(
      ECMAScriptObjects nativeobject,
      CallInfo<? extends Node> call,
      State state,
      Solver.SolverInterface c) {
    if (NativeFunctions.throwTypeErrorIfConstructor(call, state, c))
      return Value.makeBottom(new Dependency(), new DependencyGraphReference());

    switch (nativeobject) {
      case MATH_ABS: // 15.8.2.1
      case MATH_ASIN: // 15.8.2.3
      case MATH_ACOS: // 15.8.2.2
      case MATH_ATAN: // 15.8.2.4
      case MATH_CEIL: // 15.8.2.6
      case MATH_COS: // 15.8.2.7
      case MATH_EXP: // 15.8.2.8
      case MATH_FLOOR: // 15.8.2.9
      case MATH_LOG: // 15.8.2.10
      case MATH_ROUND: // 15.8.2.15
      case MATH_SIN: // 15.8.2.16
      case MATH_SQRT: // 15.8.2.17
      case MATH_TAN:
        { // 15.8.2.18
          // ##################################################
          Dependency dependency = new Dependency();
          // ##################################################

          NativeFunctions.expectParameters(nativeobject, call, c, 1, 1);
          Value num = Conversion.toNumber(NativeFunctions.readParameter(call, 0), c);

          // ##################################################
          dependency.join(num.getDependency());
          // ##################################################

          // ==================================================
          DependencyExpressionNode node =
              DependencyNode.link(Label.CALL, call.getSourceNode(), num, state);
          // ==================================================

          if (num.isMaybeSingleNum()) {
            double d = num.getNum();
            double res;
            switch (nativeobject) {
              case MATH_ABS:
                res = Math.abs(d);
                break;
              case MATH_ASIN:
                res = Math.asin(d);
                break;
              case MATH_ACOS:
                res = Math.acos(d);
                break;
              case MATH_ATAN:
                res = Math.atan(d);
                break;
              case MATH_CEIL:
                res = Math.ceil(d);
                break;
              case MATH_COS:
                res = Math.cos(d);
                break;
              case MATH_EXP:
                res = Math.exp(d);
                break;
              case MATH_FLOOR:
                res = Math.floor(d);
                break;
              case MATH_LOG:
                res = Math.log(d);
                break;
              case MATH_ROUND:
                res = Math.round(d);
                break;
              case MATH_SIN:
                res = Math.sin(d);
                break;
              case MATH_SQRT:
                res = Math.sqrt(d);
                break;
              case MATH_TAN:
                res = Math.tan(d);
                break;
              default:
                throw new RuntimeException();
            }
            return Value.makeNum(res, dependency, node.getReference());
          } else if (!num.isNotNum()) return Value.makeAnyNum(dependency, node.getReference());
          else return Value.makeBottom(dependency, node.getReference());
        }

      case MATH_ATAN2: // 15.8.2.5
      case MATH_POW:
        { // 15.8.2.13
          // ##################################################
          Dependency dependency = new Dependency();
          // ##################################################

          NativeFunctions.expectParameters(nativeobject, call, c, 2, 2);
          Value num1 = Conversion.toNumber(NativeFunctions.readParameter(call, 0), c);
          Value num2 = Conversion.toNumber(NativeFunctions.readParameter(call, 1), c);

          // ##################################################
          dependency.join(num1.getDependency());
          dependency.join(num2.getDependency());
          // ##################################################

          // ==================================================
          DependencyExpressionNode node =
              DependencyNode.link(Label.CALL, call.getSourceNode(), num1, num2, state);
          // ==================================================

          if (num1.isMaybeSingleNum() && num2.isMaybeSingleNum()) {
            double d1 = num1.getNum();
            double d2 = num2.getNum();
            double res;
            switch (nativeobject) {
              case MATH_ATAN2:
                res = Math.atan2(d1, d2);
                break;
              case MATH_POW:
                res = Math.pow(d1, d2);
                break;
              default:
                throw new RuntimeException();
            }
            return Value.makeNum(res, dependency, node.getReference());
          } else if (!num1.isNotNum() && !num2.isNotNum())
            return Value.makeAnyNum(dependency, node.getReference());
          else return Value.makeBottom(dependency, node.getReference());
        }

      case MATH_MAX:
        { // 15.8.2.11
          // ##################################################
          Dependency dependency = new Dependency();
          // ##################################################

          // ==================================================
          DependencyExpressionNode node =
              DependencyNode.link(Label.CALL, call.getSourceNode(), state);
          // ==================================================

          double res = Double.NEGATIVE_INFINITY;

          if (call.isUnknownNumberOfArgs()) {
            Value num = Conversion.toNumber(NativeFunctions.readUnknownParameter(call), c);

            // ##################################################
            dependency.join(num.getDependency());
            // ##################################################

            // ==================================================
            node.addParent(num.getDependencyGraphReference());
            // ==================================================

            if (num.isMaybeSingleNum()) res = num.getNum();
            else if (!num.isNotNum()) return Value.makeAnyNum(dependency, node.getReference());
            else return Value.makeBottom(dependency, node.getReference());
          } else
            for (int i = 0; i < call.getNumberOfArgs(); i++) {
              Value num = Conversion.toNumber(NativeFunctions.readParameter(call, i), c);

              // ##################################################
              dependency.join(num.getDependency());
              // ##################################################

              // ==================================================
              node.addParent(num.getDependencyGraphReference());
              // ==================================================

              if (num.isMaybeSingleNum()) res = Math.max(res, num.getNum());
              else if (!num.isNotNum()) return Value.makeAnyNum(dependency, node.getReference());
              else return Value.makeBottom(dependency, node.getReference());
            }
          return Value.makeNum(res, dependency, node.getReference());
        }

      case MATH_MIN:
        { // 15.8.2.12
          // ##################################################
          Dependency dependency = new Dependency();
          // ##################################################

          // ==================================================
          DependencyExpressionNode node =
              DependencyNode.link(Label.CALL, call.getSourceNode(), state);
          // ==================================================

          double res = Double.POSITIVE_INFINITY;

          if (call.isUnknownNumberOfArgs()) {
            Value num = Conversion.toNumber(NativeFunctions.readUnknownParameter(call), c);

            // ##################################################
            dependency.join(num.getDependency());
            // ##################################################

            // ==================================================
            node.addParent(num.getDependencyGraphReference());
            // ==================================================

            if (num.isMaybeSingleNum()) res = num.getNum();
            else if (!num.isNotNum()) return Value.makeAnyNum(dependency, node.getReference());
            else return Value.makeBottom(dependency, node.getReference());
          } else
            for (int i = 0; i < call.getNumberOfArgs(); i++) {
              Value num = Conversion.toNumber(NativeFunctions.readParameter(call, i), c);

              // ##################################################
              dependency.join(num.getDependency());
              // ##################################################

              // ==================================================
              node.addParent(num.getDependencyGraphReference());
              // ==================================================

              if (num.isMaybeSingleNum()) res = Math.min(res, num.getNum());
              else if (!num.isNotNum()) return Value.makeAnyNum(dependency, node.getReference());
              else return Value.makeBottom(dependency, node.getReference());
            }
          return Value.makeNum(res, dependency, node.getReference());
        }

      case MATH_RANDOM:
        { // 15.8.2.14
          // ##################################################
          Dependency dependency = new Dependency();
          // ##################################################

          // ==================================================
          DependencyExpressionNode node =
              DependencyNode.link(Label.CALL, call.getSourceNode(), state);
          // ==================================================

          NativeFunctions.expectParameters(nativeobject, call, c, 0, 0);
          return Value.makeAnyNumNotNaNInf(dependency, node.getReference());
        }

      default:
        return null;
    }
  }
Beispiel #5
0
  /*
   * Transfer functions
   */
  public static Value evaluate(
      DOMObjects nativeObject, FunctionCalls.CallInfo call, State s, Solver.SolverInterface c) {
    switch (nativeObject) {
      case ACTIVE_X_OBJECT_OPEN:
        {
          NativeFunctions.expectParameters(nativeObject, call, c, 2, 5);
          /* Value method =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 0), c);
          /* Value url =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 1), c);
          return Value.makeUndef();
        }

      case ACTIVE_X_OBJECT_SET_REQUEST_HEADER:
        {
          NativeFunctions.expectParameters(nativeObject, call, c, 2, 2);
          /* Value header =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 0), c);
          /* Value value =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 1), c);
          return Value.makeUndef();
        }

      case ACTIVE_X_OBJECT_SEND:
        {
          NativeFunctions.expectParameters(nativeObject, call, c, 0, 1);
          return Value.makeUndef();
        }

      case ACTIVE_X_OBJECT_ABORT:
        {
          NativeFunctions.expectParameters(nativeObject, call, c, 0, 0);
          return Value.makeUndef();
        }

      case ACTIVE_X_OBJECT_GET_RESPONSE_HEADER:
        {
          NativeFunctions.expectParameters(nativeObject, call, c, 1, 1);
          /* Value header =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 0), c);
          return Value.makeAnyStr();
        }

      case ACTIVE_X_OBJECT_GET_ALL_RESPONSE_HEADERS:
        {
          NativeFunctions.expectParameters(nativeObject, call, c, 0, 0);
          return Value.makeAnyStr();
        }

      case ACTIVE_X_OBJECT_CONSTRUCTOR:
        {
          // TODO: Check if this is sound.
          return Value.makeObject(INSTANCES).joinUndef();
        }

      default:
        {
          throw new AnalysisException("Unknown Native Object: " + nativeObject);
        }
    }
  }