Package org.aspectj.apache.bcel.verifier.exc

Examples of org.aspectj.apache.bcel.verifier.exc.ClassConstraintException


      checkIndex(obj, obj.getNameIndex(), CONST_Utf8);

      String name = ((ConstantUtf8) cp.getConstant(obj.getNameIndex())).getBytes();
      if (! name.equals("Code")){
        throw new ClassConstraintException("The Code attribute '"+tostring(obj)+"' is not correctly named 'Code' but '"+name+"'.");
      }

      Method m = null; // satisfy compiler
      if (!(carrier.predecessor() instanceof Method)){
        addMessage("Code attribute '"+tostring(obj)+"' is not declared in a method_info structure but in '"+carrier.predecessor()+"'. Ignored.");
        return;
      }
      else{
        m = (Method) carrier.predecessor()// we can assume this method was visited before;
                                            // i.e. the data consistency was verified.
      }

      if (obj.getCode().length == 0){
        throw new ClassConstraintException("Code array of Code attribute '"+tostring(obj)+"' (method '"+m+"') must not be empty.");
      }

      //In JustIce, the check for correct offsets into the code array is delayed to Pass 3a.
      CodeException[] exc_table = obj.getExceptionTable();
      for (int i=0; i<exc_table.length; i++){
        int exc_index = exc_table[i].getCatchType();
        if (exc_index != 0){ // if 0, it catches all Throwables
          checkIndex(obj, exc_index, CONST_Class);
          ConstantClass cc = (ConstantClass) (cp.getConstant(exc_index));
          checkIndex(cc, cc.getNameIndex(), CONST_Utf8); // cannot be sure this ConstantClass has already been visited (checked)!
          String cname = ((ConstantUtf8) cp.getConstant(cc.getNameIndex())).getBytes().replace('/','.');

          Verifier v = VerifierFactory.getVerifier(cname);
          VerificationResult vr = v.doPass1();

          if (vr != VerificationResult.VR_OK){
            throw new ClassConstraintException("Code attribute '"+tostring(obj)+"' (method '"+m+"') has an exception_table entry '"+tostring(exc_table[i])+"' that references '"+cname+"' as an Exception but it does not pass verification pass 1: "+vr);
          }
          else{
            // We cannot safely trust any other "instanceof" mechanism. We need to transitively verify
            // the ancestor hierarchy.
            JavaClass e = Repository.lookupClass(cname);
            JavaClass t = Repository.lookupClass(Type.THROWABLE.getClassName());
            JavaClass o = Repository.lookupClass(Type.OBJECT.getClassName());
            while (e != o){
              if (e == t) break; // It's a subclass of Throwable, OKAY, leave.

              v = VerifierFactory.getVerifier(e.getSuperclassName());
              vr = v.doPass1();
              if (vr != VerificationResult.VR_OK){
                throw new ClassConstraintException("Code attribute '"+tostring(obj)+"' (method '"+m+"') has an exception_table entry '"+tostring(exc_table[i])+"' that references '"+cname+"' as an Exception but '"+e.getSuperclassName()+"' in the ancestor hierachy does not pass verification pass 1: "+vr);
              }
              else{
                e = Repository.lookupClass(e.getSuperclassName());
              }
            }
            if (e != t) throw new ClassConstraintException("Code attribute '"+tostring(obj)+"' (method '"+m+"') has an exception_table entry '"+tostring(exc_table[i])+"' that references '"+cname+"' as an Exception but it is not a subclass of '"+t.getClassName()+"'.");
          }
        }
      }

      // Create object for local variables information
      // This is highly unelegant due to usage of the Visitor pattern.
      // TODO: rework it.
      int method_number = -1;
      Method[] ms = Repository.lookupClass(myOwner.getClassName()).getMethods();
      for (int mn=0; mn<ms.length; mn++){
        if (m == ms[mn]){
          method_number = mn;
          break;
        }
      }
      if (method_number < 0){ // Mmmmh. Can we be sure BCEL does not sometimes instantiate new objects?
        throw new AssertionViolatedException("Could not find a known BCEL Method object in the corresponding BCEL JavaClass object.");
      }
      localVariablesInfos[method_number] = new LocalVariablesInfo(obj.getMaxLocals());

      int num_of_lvt_attribs = 0;
      // Now iterate through the attributes the Code attribute has.
      Attribute[] atts = obj.getAttributes();
      for (int a=0; a<atts.length; a++){
        if ((! (atts[a] instanceof LineNumberTable)) &&
            (! (atts[a] instanceof LocalVariableTable))){
          addMessage("Attribute '"+tostring(atts[a])+"' as an attribute of Code attribute '"+tostring(obj)+"' (method '"+m+"') is unknown and will therefore be ignored.");
        }
        else{// LineNumberTable or LocalVariableTable
          addMessage("Attribute '"+tostring(atts[a])+"' as an attribute of Code attribute '"+tostring(obj)+"' (method '"+m+"') will effectively be ignored and is only useful for debuggers and such.");
        }

        //LocalVariableTable check (partially delayed to Pass3a).
        //Here because its easier to collect the information of the
        //(possibly more than one) LocalVariableTables belonging to
        //one certain Code attribute.
        if (atts[a] instanceof LocalVariableTable){ // checks conforming to vmspec2 4.7.9

          LocalVariableTable lvt = (LocalVariableTable) atts[a];

          checkIndex(lvt, lvt.getNameIndex(), CONST_Utf8);

          String lvtname = ((ConstantUtf8) cp.getConstant(lvt.getNameIndex())).getBytes();
          if (! lvtname.equals("LocalVariableTable")){
            throw new ClassConstraintException("The LocalVariableTable attribute '"+tostring(lvt)+"' is not correctly named 'LocalVariableTable' but '"+lvtname+"'.");
          }

          Code code = obj;

          //In JustIce, the check for correct offsets into the code array is delayed to Pass 3a.
          LocalVariable[] localvariables = lvt.getLocalVariableTable();

          for (int i=0; i<localvariables.length; i++){
            checkIndex(lvt, localvariables[i].getNameIndex(), CONST_Utf8);
            String localname = ((ConstantUtf8) cp.getConstant(localvariables[i].getNameIndex())).getBytes();
            if (!validJavaIdentifier(localname)){
              throw new ClassConstraintException("LocalVariableTable '"+tostring(lvt)+"' references a local variable by the name '"+localname+"' which is not a legal Java simple name.");
            }

            checkIndex(lvt, localvariables[i].getSignatureIndex(), CONST_Utf8);
            String localsig  = ((ConstantUtf8) (cp.getConstant(localvariables[i].getSignatureIndex()))).getBytes(); // Local signature(=descriptor)
            Type t;
            try{
              t = Type.getType(localsig);
            }
            catch (ClassFormatError cfe){ // sometimes BCEL is a little harsh describing exceptional situations.
              throw new ClassConstraintException("Illegal descriptor (==signature) '"+localsig+"' used by LocalVariable '"+tostring(localvariables[i])+"' referenced by '"+tostring(lvt)+"'.");
            }
            int localindex = localvariables[i].getIndex();
            if ( ( (t==Type.LONG || t==Type.DOUBLE)? localindex+1:localindex) >= code.getMaxLocals()){
              throw new ClassConstraintException("LocalVariableTable attribute '"+tostring(lvt)+"' references a LocalVariable '"+tostring(localvariables[i])+"' with an index that exceeds the surrounding Code attribute's max_locals value of '"+code.getMaxLocals()+"'.");
            }

            try{
              localVariablesInfos[method_number].add(localindex, localname, localvariables[i].getStartPC(), localvariables[i].getLength(), t);
            }
            catch(LocalVariableInfoInconsistentException lviie){
              throw new ClassConstraintException("Conflicting information in LocalVariableTable '"+tostring(lvt)+"' found in Code attribute '"+tostring(obj)+"' (method '"+tostring(m)+"'). "+lviie.getMessage());
            }
          }// for all local variables localvariables[i] in the LocalVariableTable attribute atts[a] END

          num_of_lvt_attribs++;
          if (num_of_lvt_attribs > obj.getMaxLocals()){
            throw new ClassConstraintException("Number of LocalVariableTable attributes of Code attribute '"+tostring(obj)+"' (method '"+tostring(m)+"') exceeds number of local variable slots '"+obj.getMaxLocals()+"' ('There may be no more than one LocalVariableTable attribute per local variable in the Code attribute.').");
          }
        }// if atts[a] instanceof LocalVariableTable END
      }// for all attributes atts[a] END
    }// visitCode(Code) END
View Full Code Here


      // incorrectly named, it's the Exceptions attribute (vmspec2 4.7.4)
      checkIndex(obj, obj.getNameIndex(), CONST_Utf8);

      String name = ((ConstantUtf8) cp.getConstant(obj.getNameIndex())).getBytes();
      if (! name.equals("Exceptions")){
        throw new ClassConstraintException("The Exceptions attribute '"+tostring(obj)+"' is not correctly named 'Exceptions' but '"+name+"'.");
      }

      int[] exc_indices = obj.getExceptionIndexTable();

      for (int i=0; i<exc_indices.length; i++){
        checkIndex(obj, exc_indices[i], CONST_Class);

        ConstantClass cc = (ConstantClass) (cp.getConstant(exc_indices[i]));
        checkIndex(cc, cc.getNameIndex(), CONST_Utf8); // cannot be sure this ConstantClass has already been visited (checked)!
        String cname = ((ConstantUtf8) cp.getConstant(cc.getNameIndex())).getBytes().replace('/','.'); //convert internal notation on-the-fly to external notation

        Verifier v = VerifierFactory.getVerifier(cname);
        VerificationResult vr = v.doPass1();

        if (vr != VerificationResult.VR_OK){
          throw new ClassConstraintException("Exceptions attribute '"+tostring(obj)+"' references '"+cname+"' as an Exception but it does not pass verification pass 1: "+vr);
        }
        else{
          // We cannot safely trust any other "instanceof" mechanism. We need to transitively verify
          // the ancestor hierarchy.
          JavaClass e = Repository.lookupClass(cname);
          JavaClass t = Repository.lookupClass(Type.THROWABLE.getClassName());
          JavaClass o = Repository.lookupClass(Type.OBJECT.getClassName());
          while (e != o){
            if (e == t) break; // It's a subclass of Throwable, OKAY, leave.

            v = VerifierFactory.getVerifier(e.getSuperclassName());
            vr = v.doPass1();
            if (vr != VerificationResult.VR_OK){
              throw new ClassConstraintException("Exceptions attribute '"+tostring(obj)+"' references '"+cname+"' as an Exception but '"+e.getSuperclassName()+"' in the ancestor hierachy does not pass verification pass 1: "+vr);
            }
            else{
              e = Repository.lookupClass(e.getSuperclassName());
            }
          }
          if (e != t) throw new ClassConstraintException("Exceptions attribute '"+tostring(obj)+"' references '"+cname+"' as an Exception but it is not a subclass of '"+t.getClassName()+"'.");
        }
      }
    }
View Full Code Here

    public void visitLineNumberTable(LineNumberTable obj){//vmspec2 4.7.8
      checkIndex(obj, obj.getNameIndex(), CONST_Utf8);

      String name = ((ConstantUtf8) cp.getConstant(obj.getNameIndex())).getBytes();
      if (! name.equals("LineNumberTable")){
        throw new ClassConstraintException("The LineNumberTable attribute '"+tostring(obj)+"' is not correctly named 'LineNumberTable' but '"+name+"'.");
      }

      //In JustIce,this check is delayed to Pass 3a.
      //LineNumber[] linenumbers = obj.getLineNumberTable();
      // ...validity check...
View Full Code Here

      cp = _jc.getConstantPool();
    }
   
    public void visitConstantFieldref(ConstantFieldref obj){
      if (obj.getTag() != Constants.CONSTANT_Fieldref){
        throw new ClassConstraintException("ConstantFieldref '"+tostring(obj)+"' has wrong tag!");
      }
      int name_and_type_index = obj.getNameAndTypeIndex();
      ConstantNameAndType cnat = (ConstantNameAndType) (cp.getConstant(name_and_type_index));
      String name = ((ConstantUtf8) (cp.getConstant(cnat.getNameIndex()))).getBytes(); // Field or Method name
      if (!validFieldName(name)){
        throw new ClassConstraintException("Invalid field name '"+name+"' referenced by '"+tostring(obj)+"'.");
      }
     
      int class_index = obj.getClassIndex();
      ConstantClass cc = (ConstantClass) (cp.getConstant(class_index));
      String className = ((ConstantUtf8) (cp.getConstant(cc.getNameIndex()))).getBytes(); // Class Name in internal form
      if (! validClassName(className)){
        throw new ClassConstraintException("Illegal class name '"+className+"' used by '"+tostring(obj)+"'.");
      }

      String sig  = ((ConstantUtf8) (cp.getConstant(cnat.getSignatureIndex()))).getBytes(); // Field or Method signature(=descriptor)
           
      try{
        Type.getType(sig); /* Don't need the return value */
      }
      catch (ClassFormatError cfe){
        // Well, BCEL sometimes is a little harsh describing exceptional situations.
        throw new ClassConstraintException("Illegal descriptor (==signature) '"+sig+"' used by '"+tostring(obj)+"'.");
      }
    }
View Full Code Here

      }
    }

    public void visitConstantMethodref(ConstantMethodref obj){
      if (obj.getTag() != Constants.CONSTANT_Methodref){
        throw new ClassConstraintException("ConstantMethodref '"+tostring(obj)+"' has wrong tag!");
      }
      int name_and_type_index = obj.getNameAndTypeIndex();
      ConstantNameAndType cnat = (ConstantNameAndType) (cp.getConstant(name_and_type_index));
      String name = ((ConstantUtf8) (cp.getConstant(cnat.getNameIndex()))).getBytes(); // Field or Method name
      if (!validClassMethodName(name)){
        throw new ClassConstraintException("Invalid (non-interface) method name '"+name+"' referenced by '"+tostring(obj)+"'.");
      }

      int class_index = obj.getClassIndex();
      ConstantClass cc = (ConstantClass) (cp.getConstant(class_index));
      String className = ((ConstantUtf8) (cp.getConstant(cc.getNameIndex()))).getBytes(); // Class Name in internal form
      if (! validClassName(className)){
        throw new ClassConstraintException("Illegal class name '"+className+"' used by '"+tostring(obj)+"'.");
      }

      String sig  = ((ConstantUtf8) (cp.getConstant(cnat.getSignatureIndex()))).getBytes(); // Field or Method signature(=descriptor)
           
      try{
        Type   t  = Type.getReturnType(sig);
        if ( name.equals(CONSTRUCTOR_NAME) && (t != Type.VOID) ){
          throw new ClassConstraintException("Instance initialization method must have VOID return type.");
        }
      }
      catch (ClassFormatError cfe){
        // Well, BCEL sometimes is a little harsh describing exceptional situations.
        throw new ClassConstraintException("Illegal descriptor (==signature) '"+sig+"' used by '"+tostring(obj)+"'.");
      }
    }
View Full Code Here

      }
    }

    public void visitConstantInterfaceMethodref(ConstantInterfaceMethodref obj){
      if (obj.getTag() != Constants.CONSTANT_InterfaceMethodref){
        throw new ClassConstraintException("ConstantInterfaceMethodref '"+tostring(obj)+"' has wrong tag!");
      }
      int name_and_type_index = obj.getNameAndTypeIndex();
      ConstantNameAndType cnat = (ConstantNameAndType) (cp.getConstant(name_and_type_index));
      String name = ((ConstantUtf8) (cp.getConstant(cnat.getNameIndex()))).getBytes(); // Field or Method name
      if (!validInterfaceMethodName(name)){
        throw new ClassConstraintException("Invalid (interface) method name '"+name+"' referenced by '"+tostring(obj)+"'.");
      }

      int class_index = obj.getClassIndex();
      ConstantClass cc = (ConstantClass) (cp.getConstant(class_index));
      String className = ((ConstantUtf8) (cp.getConstant(cc.getNameIndex()))).getBytes(); // Class Name in internal form
      if (! validClassName(className)){
        throw new ClassConstraintException("Illegal class name '"+className+"' used by '"+tostring(obj)+"'.");
      }

      String sig  = ((ConstantUtf8) (cp.getConstant(cnat.getSignatureIndex()))).getBytes(); // Field or Method signature(=descriptor)
           
      try{
        Type   t  = Type.getReturnType(sig);
        if ( name.equals(STATIC_INITIALIZER_NAME) && (t != Type.VOID) ){
          addMessage("Class or interface initialization method '"+STATIC_INITIALIZER_NAME+"' usually has VOID return type instead of '"+t+"'. Note this is really not a requirement of The Java Virtual Machine Specification, Second Edition.");
        }
      }
      catch (ClassFormatError cfe){
        // Well, BCEL sometimes is a little harsh describing exceptional situations.
        throw new ClassConstraintException("Illegal descriptor (==signature) '"+sig+"' used by '"+tostring(obj)+"'.");
      }

    }
View Full Code Here

    while (supidx != 0){
      supidx = jc.getSuperclassNameIndex();
   
      if (supidx == 0){
        if (jc != Repository.lookupClass(Type.OBJECT.getClassName())){
          throw new ClassConstraintException("Superclass of '"+jc.getClassName()+"' missing but not "+Type.OBJECT.getClassName()+" itself!");
        }
      }
      else{
        String supername = jc.getSuperclassName();
        if (! hs.add(supername)){  // If supername already is in the list
          throw new ClassConstraintException("Circular superclass hierarchy detected.");
        }
        Verifier v = VerifierFactory.getVerifier(supername);
        VerificationResult vr = v.doPass1();

        if (vr != VerificationResult.VR_OK){
          throw new ClassConstraintException("Could not load in ancestor class '"+supername+"'.");
        }
        jc = Repository.lookupClass(supername);

        if (jc.isFinal()){
          throw new ClassConstraintException("Ancestor class '"+supername+"' has the FINAL access modifier and must therefore not be subclassed.");
        }
      }
    }
  }
View Full Code Here

      for (int i=0; i<methods.length; i++){
        String name_and_sig = (methods[i].getName()+methods[i].getSignature());

        if (hashmap.containsKey(name_and_sig)){
          if (methods[i].isFinal()){
            throw new ClassConstraintException("Method '"+name_and_sig+"' in class '"+hashmap.get(name_and_sig)+"' overrides the final (not-overridable) definition in class '"+jc.getClassName()+"'.");
          }
          else{
            if (!methods[i].isStatic()){ // static methods don't inherit
              hashmap.put(name_and_sig, jc.getClassName());
            }
View Full Code Here

              offsets.add(offset);
            }
            continue lineNumber_loop;
          }
        }
        throw new ClassConstraintException("Code attribute '"+code+"' has a LineNumberTable attribute '"+code.getLineNumberTable()+"' referring to a code offset ('"+lineNumbers[i].getStartPC()+"') that does not exist.");
      }
    }

    ///////////////////////////
    // LocalVariableTable(s) //
    ///////////////////////////
    /* We cannot use code.getLocalVariableTable() because there could be more
       than only one. This is a bug in BCEL. */
    Attribute[] atts = code.getAttributes();
    for (int a=0; a<atts.length; a++){
      if (atts[a] instanceof LocalVariableTable){
        LocalVariableTable lvt = (LocalVariableTable) atts[a];
        if (lvt != null){
          LocalVariable[] localVariables = lvt.getLocalVariableTable();
          for (int i=0; i<localVariables.length; i++){
            int startpc = localVariables[i].getStartPC();
            int length  = localVariables[i].getLength();
       
            if (!contains(instructionPositions, startpc)){
              throw new ClassConstraintException("Code attribute '"+code+"' has a LocalVariableTable attribute '"+code.getLocalVariableTable()+"' referring to a code offset ('"+startpc+"') that does not exist.");
            }
            if ( (!contains(instructionPositions, startpc+length)) && (startpc+length != codeLength) ){
              throw new ClassConstraintException("Code attribute '"+code+"' has a LocalVariableTable attribute '"+code.getLocalVariableTable()+"' referring to a code offset start_pc+length ('"+(startpc+length)+"') that does not exist.");
            }
          }
        }
      }
    }
   
    ////////////////////
    // ExceptionTable //
    ////////////////////
    // In BCEL's "classfile" API, the startPC/endPC-notation is
    // inclusive/exclusive as in the Java Virtual Machine Specification.
    // WARNING: This is not true for BCEL's "generic" API.
    CodeException[] exceptionTable = code.getExceptionTable();
    for (int i=0; i<exceptionTable.length; i++){
      int startpc = exceptionTable[i].getStartPC();
      int endpc = exceptionTable[i].getEndPC();
      int handlerpc = exceptionTable[i].getHandlerPC();
      if (startpc >= endpc){
        throw new ClassConstraintException("Code attribute '"+code+"' has an exception_table entry '"+exceptionTable[i]+"' that has its start_pc ('"+startpc+"') not smaller than its end_pc ('"+endpc+"').");
      }
      if (!contains(instructionPositions, startpc)){
        throw new ClassConstraintException("Code attribute '"+code+"' has an exception_table entry '"+exceptionTable[i]+"' that has a non-existant bytecode offset as its start_pc ('"+startpc+"').");
      }
      if ( (!contains(instructionPositions, endpc)) && (endpc != codeLength)){
        throw new ClassConstraintException("Code attribute '"+code+"' has an exception_table entry '"+exceptionTable[i]+"' that has a non-existant bytecode offset as its end_pc ('"+startpc+"') [that is also not equal to code_length ('"+codeLength+"')].");
      }
      if (!contains(instructionPositions, handlerpc)){
        throw new ClassConstraintException("Code attribute '"+code+"' has an exception_table entry '"+exceptionTable[i]+"' that has a non-existant bytecode offset as its handler_pc ('"+handlerpc+"').");
      }
    }
  }
View Full Code Here

TOP

Related Classes of org.aspectj.apache.bcel.verifier.exc.ClassConstraintException

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.