Example #1
0
 public LHS toLHS(CallStack callstack, Interpreter interpreter) throws EvalError {
   try {
     return getName(callstack.top()).toLHS(callstack, interpreter);
   } catch (UtilEvalError e) {
     throw e.toEvalError(this, callstack);
   }
 }
 // Throws a program exception with the given message.
 private void error(String message) throws ProgramException {
   throw new ProgramException(
       message
           + " in "
           + callStack.getTopFunction()
           + "."
           + currentInstruction.getIndexInFunction());
 }
 Object toObject(CallStack callstack, Interpreter interpreter, boolean forceClass)
     throws EvalError {
   try {
     return getName(callstack.top()).toObject(callstack, interpreter, forceClass);
   } catch (UtilEvalError e) {
     throw e.toEvalError(this, callstack);
   }
 }
Example #4
0
 public Class toClass(CallStack callstack, Interpreter interpreter) throws EvalError {
   try {
     return getName(callstack.top()).toClass();
   } catch (ClassNotFoundException e) {
     throw new EvalError(e.getMessage(), this, callstack);
   } catch (UtilEvalError e2) {
     // ClassPathException is a type of UtilEvalError
     throw e2.toEvalError(this, callstack);
   }
 }
 private void afterExecutionImpl(final String sqlString) {
   if (JiraSystemProperties.getInstance().isXsrfDiagnostics()) {
     final String requestURL = MDC.get("jira.request.url");
     if (isMutatingSQL(sqlString)) {
       HttpServletRequest request = ActionContext.getRequest();
       if (request != null
           && request.getAttribute(XSRF_VULNERABILITY_DETECTION_SQLINTERCEPTOR_DONE) == null) {
         // setting this into the request will make things a lot faster
         request.setAttribute(XSRF_VULNERABILITY_DETECTION_SQLINTERCEPTOR_DONE, "true");
         CallStack callStack = new CallStack();
         if (callStack.hasMethodsWeAreInterestedIn() && !callStack.isProtectedAction()) {
           log.error("XSRF VULNERABILITY DETECTED");
           log.error("requestURL: " + requestURL);
           log.error("sql: " + sqlString);
           log.error("CallStack:", callStack);
         }
       }
     }
   }
 }
  /**
   * Calls a function according to the given function number stating that the given number of
   * arguments have been pushed onto the stack
   *
   * <p>If callerIsBuiltIn then the caller is a builtIn function that called this function through
   * callFunctionFromBuiltIn. If address is -1 then a native function should be looked up and
   * called.
   */
  public void callFunction(
      short address, short numberOfArguments, String functionName, boolean callerIsBuiltIn)
      throws ProgramException {
    stackFrames.addElement(new Integer(workingStackSegment.getStartAddress()));
    workingStackSegment.setStartAddress(getSP() + 5);

    if (callerIsBuiltIn) {
      pushValue(MAIN_STACK, VMProgram.BUILTIN_FUNCTION_ADDRESS);
    } else {
      pushValue(MAIN_STACK, program.getPC());
    }
    pushFromRAM(MAIN_STACK, Definitions.LOCAL_POINTER_ADDRESS);
    pushFromRAM(MAIN_STACK, Definitions.ARG_POINTER_ADDRESS);
    pushFromRAM(MAIN_STACK, Definitions.THIS_POINTER_ADDRESS);
    pushFromRAM(MAIN_STACK, Definitions.THAT_POINTER_ADDRESS);
    ram.setValueAt(
        Definitions.ARG_POINTER_ADDRESS, (short) (getSP() - numberOfArguments - 5), false);
    ram.setValueAt(Definitions.LOCAL_POINTER_ADDRESS, getSP(), false);

    // enable in the arg segment only the number of args that were sent to the called function.
    argSegment.setEnabledRange(
        argSegment.getStartAddress(), argSegment.getStartAddress() + numberOfArguments - 1, true);

    if (address == VMProgram.BUILTIN_FUNCTION_ADDRESS) {
      // Perform some actions normally done in the function() method
      localSegment.setEnabledRange(
          localSegment.getStartAddress(),
          localSegment.getStartAddress() - 1,
          true); // no local variables
      callStack.pushFunction(functionName + " (built-in)");
      staticSegment.setEnabledRange(0, -1, true); // empty static segment
      // Read parameters from the stack
      short[] params = new short[numberOfArguments];
      for (int i = 0; i < numberOfArguments; ++i) {
        params[i] = argSegment.getValueAt(i);
      }
      // Call the built-in implementation
      builtInFunctionsRunner.callBuiltInFunction(functionName, params);
    } else if (address >= 0 || address < program.getSize()) {
      program.setPC(address);
      program.setPC(address); // make sure previouspc isn't pc-1
      // which might happen if the calling
      // function called this function in the
      // last line before the "return" and
      // was declared just before this function.
      // In this case encountering the "function"
      // command will issue an error about
      // "missing return"...
    } else {
      error("Illegal call address");
    }
  }
Example #7
0
  public String getScriptStackTrace() {
    if (callstack == null) return "<Unknown>";

    String trace = "";
    CallStack stack = callstack.copy();
    while (stack.depth() > 0) {
      NameSpace ns = stack.pop();
      SimpleNode node = ns.getNode();
      if (ns.isMethod) {
        trace = trace + "\nCalled from method: " + ns.getName();
        if (node != null)
          trace +=
              " : at Line: "
                  + node.getLineNumber()
                  + " : in file: "
                  + node.getSourceFile()
                  + " : "
                  + node.getText();
      }
    }

    return trace;
  }
  /**
   * Here Starts the code of a function according to the given function name that has the given
   * number of local variables.
   *
   * @param numberOfLocals The number of local variables
   */
  public void function(short numberOfLocals) throws ProgramException {

    short newSP = (short) (getSP() + numberOfLocals);
    checkSP(newSP);
    workingStackSegment.setStartAddress(newSP);

    // disable non relevant range of the local segment - enable only the number
    // of locals of this function.
    localSegment.setEnabledRange(getSP(), newSP - 1, true);

    for (int i = 0; i < numberOfLocals; i++) {
      pushValue(MAIN_STACK, (short) 0);
    }

    String functionName = currentInstruction.getStringArg();

    // adds the new function to the top of the call stack.
    callStack.pushFunction(functionName);

    // sets the static segment range
    setStaticRange(functionName);
  }
  /**
   * Parse the BSHBlock for for the class definition and generate the class using ClassGenerator.
   */
  public static Class generateClassImpl(
      String name,
      Modifiers modifiers,
      Class[] interfaces,
      Class superClass,
      BSHBlock block,
      boolean isInterface,
      CallStack callstack,
      Interpreter interpreter)
      throws EvalError {
    // Scripting classes currently requires accessibility
    // This can be eliminated with a bit more work.
    try {
      Capabilities.setAccessibility(true);
    } catch (Capabilities.Unavailable e) {
      throw new EvalError(
          "Defining classes currently requires reflective Accessibility.", block, callstack);
    }

    NameSpace enclosingNameSpace = callstack.top();
    String packageName = enclosingNameSpace.getPackage();
    String className =
        enclosingNameSpace.isClass ? (enclosingNameSpace.getName() + "$" + name) : name;
    String fqClassName = packageName == null ? className : packageName + "." + className;

    BshClassManager bcm = interpreter.getClassManager();
    // Race condition here...
    bcm.definingClass(fqClassName);

    // Create the class static namespace
    NameSpace classStaticNameSpace = new NameSpace(enclosingNameSpace, className);
    classStaticNameSpace.isClass = true;

    callstack.push(classStaticNameSpace);

    // Evaluate any inner class class definitions in the block
    // effectively recursively call this method for contained classes first
    block.evalBlock(callstack, interpreter, true /*override*/, ClassNodeFilter.CLASSCLASSES);

    // Generate the type for our class
    Variable[] variables = getDeclaredVariables(block, callstack, interpreter, packageName);
    DelayedEvalBshMethod[] methods = getDeclaredMethods(block, callstack, interpreter, packageName);

    ClassGeneratorUtil classGenerator =
        new ClassGeneratorUtil(
            modifiers,
            className,
            packageName,
            superClass,
            interfaces,
            variables,
            methods,
            classStaticNameSpace,
            isInterface);
    byte[] code = classGenerator.generateClass();

    // if debug, write out the class file to debugClasses directory
    if (DEBUG_DIR != null)
      try {
        FileOutputStream out = new FileOutputStream(DEBUG_DIR + '/' + className + ".class");
        out.write(code);
        out.close();
      } catch (IOException e) {
        throw new IllegalStateException(
            "cannot create file " + DEBUG_DIR + '/' + className + ".class", e);
      }

    // Define the new class in the classloader
    Class genClass = bcm.defineClass(fqClassName, code);

    // import the unq name into parent
    enclosingNameSpace.importClass(fqClassName.replace('$', '.'));

    try {
      classStaticNameSpace.setLocalVariable(
          ClassGeneratorUtil.BSHINIT, block, false /*strictJava*/);
    } catch (UtilEvalError e) {
      throw new InterpreterError("unable to init static: " + e);
    }

    // Give the static space its class static import
    // important to do this after all classes are defined
    classStaticNameSpace.setClassStatic(genClass);

    // evaluate the static portion of the block in the static space
    block.evalBlock(callstack, interpreter, true /*override*/, ClassNodeFilter.CLASSSTATIC);

    callstack.pop();

    if (!genClass.isInterface()) {
      // Set the static bsh This callback
      String bshStaticFieldName = ClassGeneratorUtil.BSHSTATIC + className;
      try {
        LHS lhs = Reflect.getLHSStaticField(genClass, bshStaticFieldName);
        lhs.assign(classStaticNameSpace.getThis(interpreter), false /*strict*/);
      } catch (Exception e) {
        throw new InterpreterError("Error in class gen setup: " + e);
      }
    }

    bcm.doneDefiningClass(fqClassName);
    return genClass;
  }
 public Object eval(CallStack callstack, Interpreter interpreter) throws EvalError {
   Class elementType = null;
   SimpleNode expression;
   SimpleNode statement = null;
   NameSpace enclosingNameSpace = callstack.top();
   SimpleNode firstNode = ((SimpleNode) jjtGetChild(0));
   int nodeCount = jjtGetNumChildren();
   if (firstNode instanceof BSHType) {
     elementType = ((BSHType) firstNode).getType(callstack, interpreter);
     expression = ((SimpleNode) jjtGetChild(1));
     if (nodeCount > 2) {
       statement = ((SimpleNode) jjtGetChild(2));
     }
   } else {
     expression = firstNode;
     if (nodeCount > 1) {
       statement = ((SimpleNode) jjtGetChild(1));
     }
   }
   BlockNameSpace eachNameSpace = new BlockNameSpace(enclosingNameSpace);
   callstack.swap(eachNameSpace);
   final Object iteratee = expression.eval(callstack, interpreter);
   if (iteratee == Primitive.NULL) {
     throw new EvalError(
         "The collection, array, map, iterator, or "
             + "enumeration portion of a for statement cannot be null.",
         this,
         callstack);
   }
   CollectionManager cm = CollectionManager.getCollectionManager();
   if (!cm.isBshIterable(iteratee)) {
     throw new EvalError("Can't iterate over type: " + iteratee.getClass(), this, callstack);
   }
   BshIterator iterator = cm.getBshIterator(iteratee);
   Object returnControl = Primitive.VOID;
   while (iterator.hasNext()) {
     try {
       Object value = iterator.next();
       if (value == null) {
         value = Primitive.NULL;
       }
       if (elementType != null) {
         eachNameSpace.setTypedVariable(
             varName /*name*/, elementType /*type*/, value /*value*/, new Modifiers() /*none*/);
       } else {
         eachNameSpace.setVariable(varName, value, false);
       }
     } catch (UtilEvalError e) {
       throw e.toEvalError("for loop iterator variable:" + varName, this, callstack);
     }
     boolean breakout = false; // switch eats a multi-level break here?
     if (statement != null) {
       // not empty statement
       Object ret = statement.eval(callstack, interpreter);
       if (ret instanceof ReturnControl) {
         switch (((ReturnControl) ret).kind) {
           case RETURN:
             returnControl = ret;
             breakout = true;
             break;
           case CONTINUE:
             break;
           case BREAK:
             breakout = true;
             break;
         }
       }
     }
     if (breakout) {
       break;
     }
   }
   callstack.swap(enclosingNameSpace);
   return returnControl;
 }
  /** Returns the value of the function to the top of the stack. */
  public void returnFromFunction() throws ProgramException {

    // make sure that there's somewhere to return to (old local <> 0)
    if (stackSegment.getValueAt(Definitions.LOCAL_POINTER_ADDRESS) == 0)
      throw new ProgramException(
          "Nowhere to return to in "
              + getCallStack().getTopFunction()
              + "."
              + getCurrentInstruction().getIndexInFunction());

    // done in order to clear the method stack's contents
    workingStackSegment.setStartAddress(getSP());

    bus.send(ram, Definitions.LOCAL_POINTER_ADDRESS, ram, Definitions.R13_ADDRESS); // R13 = lcl
    bus.send(
        stackSegment,
        stackSegment.getValueAt(Definitions.LOCAL_POINTER_ADDRESS) - 5,
        ram,
        Definitions.R14_ADDRESS); // R14 = return address
    bus.send(
        stackSegment,
        getSP() - 1,
        stackSegment,
        ram.getValueAt(Definitions.ARG_POINTER_ADDRESS)); // *arg = return value
    setSP((short) (ram.getValueAt(Definitions.ARG_POINTER_ADDRESS) + 1)); // SP = arg + 1
    bus.send(
        stackSegment,
        ram.getValueAt(Definitions.R13_ADDRESS) - 1,
        ram,
        Definitions.THAT_POINTER_ADDRESS); // that = *(R13 - 1)
    bus.send(
        stackSegment,
        ram.getValueAt(Definitions.R13_ADDRESS) - 2,
        ram,
        Definitions.THIS_POINTER_ADDRESS); // this = *(R13 - 2)
    bus.send(
        stackSegment,
        ram.getValueAt(Definitions.R13_ADDRESS) - 3,
        ram,
        Definitions.ARG_POINTER_ADDRESS); // arg = *(R13 - 3)
    bus.send(
        stackSegment,
        ram.getValueAt(Definitions.R13_ADDRESS) - 4,
        ram,
        Definitions.LOCAL_POINTER_ADDRESS); // lcl = *(R13 - 4)

    // removes the top function from the call stack
    callStack.popFunction();

    // check whether there is a "calling frame"
    if (stackFrames.size() > 0) {
      // retrieve stack frame address of old function
      int frameAddress = ((Integer) stackFrames.lastElement()).intValue();
      stackFrames.removeElementAt(stackFrames.size() - 1);
      workingStackSegment.setStartAddress(frameAddress);

      // disable non relevant range of the local segment - enable only the locals
      // of the function that we returned to.
      localSegment.setEnabledRange(
          Math.max(localSegment.getStartAddress(), Definitions.STACK_START_ADDRESS),
          frameAddress - 1,
          true);

      // enable in the arg segment only the number of args that were sent to the function
      // that we returned to.
      argSegment.setEnabledRange(
          argSegment.getStartAddress(), localSegment.getStartAddress() - 6, true);

      // enable this, that according to their retrieved pointers
      thisSegment.setEnabledRange(
          Math.max(thisSegment.getStartAddress(), Definitions.HEAP_START_ADDRESS),
          Definitions.HEAP_END_ADDRESS,
          true);
      thatSegment.setEnabledRange(
          Math.max(thatSegment.getStartAddress(), Definitions.HEAP_START_ADDRESS),
          Definitions.SCREEN_END_ADDRESS,
          true);
    } /* else {
      	error("Nowhere to return to");
      } */
    // Allow return if we previously had "function" even with no call -
    // For the SimpleFunction test

    short returnAddress = ram.getValueAt(Definitions.R14_ADDRESS);
    if (returnAddress == VMProgram.BUILTIN_FUNCTION_ADDRESS) {
      staticSegment.setEnabledRange(0, -1, true); // empty static segment
      builtInFunctionsRunner.returnToBuiltInFunction(popValue(METHOD_STACK));
    } else if (returnAddress >= 0 && returnAddress < program.getSize()) {
      // sets the static segment range
      if (stackFrames.size() > 0) {
        setStaticRange(callStack.getTopFunction());
      } else {
        staticSegment.setStartAddress(Definitions.VAR_START_ADDRESS);
        staticSegment.setEnabledRange(
            Definitions.VAR_START_ADDRESS, Definitions.VAR_END_ADDRESS - 1, true);
      }
      program.setPC((short) (returnAddress - 1)); // set previousPC correctly
      program.setPC(returnAddress); // pc = *sp
    } else {
      error("Illegal return address");
    }
  }
  /**
   * Executes the current instruction (Program at pc). Returns false if END command, true otherwise.
   */
  public void executeInstruction() throws ProgramException {
    currentInstruction = program.getNextInstruction();

    if (currentInstruction == null) throw new ProgramException("No more instructions to execute");

    switch (currentInstruction.getOpCode()) {
      case HVMInstructionSet.ADD_CODE:
        add();
        break;
      case HVMInstructionSet.SUBSTRACT_CODE:
        substract();
        break;
      case HVMInstructionSet.NEGATE_CODE:
        negate();
        break;
      case HVMInstructionSet.EQUAL_CODE:
        equal();
        break;
      case HVMInstructionSet.GREATER_THAN_CODE:
        greaterThan();
        break;
      case HVMInstructionSet.LESS_THAN_CODE:
        lessThan();
        break;
      case HVMInstructionSet.AND_CODE:
        and();
        break;
      case HVMInstructionSet.OR_CODE:
        or();
        break;
      case HVMInstructionSet.NOT_CODE:
        not();
        break;

      case HVMInstructionSet.PUSH_CODE:
        push(currentInstruction.getArg0(), currentInstruction.getArg1());
        break;
      case HVMInstructionSet.POP_CODE:
        pop(currentInstruction.getArg0(), currentInstruction.getArg1());
        break;

      case HVMInstructionSet.GOTO_CODE:
        goTo(currentInstruction.getArg0());
        break;
      case HVMInstructionSet.IF_GOTO_CODE:
        ifGoTo(currentInstruction.getArg0());
        break;

      case HVMInstructionSet.FUNCTION_CODE:
        if (program.getCurrentPC() == program.getPreviousPC() + 1)
          throw new ProgramException("Missing return in " + callStack.getTopFunction());

        function(currentInstruction.getArg0());
        break;
      case HVMInstructionSet.RETURN_CODE:
        returnFromFunction();
        break;
      case HVMInstructionSet.CALL_CODE:
        callFunction(
            currentInstruction.getArg0(),
            currentInstruction.getArg1(),
            currentInstruction.getStringArg(),
            false);
        break;
    }
  }
Example #13
0
 public EvalError(String s, SimpleNode node, CallStack callstack) {
   setMessage(s);
   this.node = node;
   // freeze the callstack for the stack trace.
   if (callstack != null) this.callstack = callstack.copy();
 }