⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pass2verifier.java

📁 该开源工具主要用于class文件的操作
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
			CONST_Integer = org.apache.bcel.classfile.ConstantInteger.class;			CONST_Float = org.apache.bcel.classfile.ConstantFloat.class;			CONST_Long = org.apache.bcel.classfile.ConstantLong.class;			CONST_Double = org.apache.bcel.classfile.ConstantDouble.class;			CONST_NameAndType = org.apache.bcel.classfile.ConstantNameAndType.class;			CONST_Utf8 = org.apache.bcel.classfile.ConstantUtf8.class;					carrier = new DescendingVisitor(_jc, this);			carrier.visit();		}				private void checkIndex(Node referrer, int index, Class shouldbe){			if ((index < 0) || (index >= cplen)){				throw new ClassConstraintException("Invalid index '"+index+"' used by '"+tostring(referrer)+"'.");			}			Constant c = cp.getConstant(index);			if (! shouldbe.isInstance(c)){				String isnot = shouldbe.toString().substring(shouldbe.toString().lastIndexOf(".")+1); //Cut all before last "."				throw new ClassCastException("Illegal constant '"+tostring(c)+"' at index '"+index+"'. '"+tostring(referrer)+"' expects a '"+shouldbe+"'.");			}		}		///////////////////////////////////////		// ClassFile structure (vmspec2 4.1) //		///////////////////////////////////////		public void visitJavaClass(JavaClass obj){			Attribute[] atts = obj.getAttributes();			boolean foundSourceFile = false;			boolean foundInnerClasses = false;						// Is there an InnerClass referenced?			// This is a costly check; existing verifiers don't do it!			boolean hasInnerClass = new InnerClassDetector(jc).innerClassReferenced();						for (int i=0; i<atts.length; i++){				if ((! (atts[i] instanceof SourceFile)) &&				    (! (atts[i] instanceof Deprecated))     &&				    (! (atts[i] instanceof InnerClasses)) &&				    (! (atts[i] instanceof Synthetic))){					addMessage("Attribute '"+tostring(atts[i])+"' as an attribute of the ClassFile structure '"+tostring(obj)+"' is unknown and will therefore be ignored.");				}								if (atts[i] instanceof SourceFile){					if (foundSourceFile == false) foundSourceFile = true;					else throw new ClassConstraintException("A ClassFile structure (like '"+tostring(obj)+"') may have no more than one SourceFile attribute."); //vmspec2 4.7.7				}							if (atts[i] instanceof InnerClasses){					if (foundInnerClasses == false) foundInnerClasses = true;					else{						if (hasInnerClass){							throw new ClassConstraintException("A Classfile structure (like '"+tostring(obj)+"') must have exactly one InnerClasses attribute if at least one Inner Class is referenced (which is the case). More than one InnerClasses attribute was found.");						}					}					if (!hasInnerClass){						addMessage("No referenced Inner Class found, but InnerClasses attribute '"+tostring(atts[i])+"' found. Strongly suggest removal of that attribute.");					}				}			}			if (hasInnerClass && !foundInnerClasses){				//throw new ClassConstraintException("A Classfile structure (like '"+tostring(obj)+"') must have exactly one InnerClasses attribute if at least one Inner Class is referenced (which is the case). No InnerClasses attribute was found.");				//vmspec2, page 125 says it would be a constraint: but existing verifiers				//don't check it and javac doesn't satisfy it when it comes to anonymous				//inner classes				addMessage("A Classfile structure (like '"+tostring(obj)+"') must have exactly one InnerClasses attribute if at least one Inner Class is referenced (which is the case). No InnerClasses attribute was found.");			}			}		/////////////////////////////		// CONSTANTS (vmspec2 4.4) //		/////////////////////////////		public void visitConstantClass(ConstantClass obj){			if (obj.getTag() != Constants.CONSTANT_Class){				throw new ClassConstraintException("Wrong constant tag in '"+tostring(obj)+"'.");			}			checkIndex(obj, obj.getNameIndex(), CONST_Utf8);				}		public void visitConstantFieldref(ConstantFieldref obj){			if (obj.getTag() != Constants.CONSTANT_Fieldref){				throw new ClassConstraintException("Wrong constant tag in '"+tostring(obj)+"'.");			}			checkIndex(obj, obj.getClassIndex(), CONST_Class);			checkIndex(obj, obj.getNameAndTypeIndex(), CONST_NameAndType);		}		public void visitConstantMethodref(ConstantMethodref obj){			if (obj.getTag() != Constants.CONSTANT_Methodref){				throw new ClassConstraintException("Wrong constant tag in '"+tostring(obj)+"'.");			}			checkIndex(obj, obj.getClassIndex(), CONST_Class);			checkIndex(obj, obj.getNameAndTypeIndex(), CONST_NameAndType);		}		public void visitConstantInterfaceMethodref(ConstantInterfaceMethodref obj){			if (obj.getTag() != Constants.CONSTANT_InterfaceMethodref){				throw new ClassConstraintException("Wrong constant tag in '"+tostring(obj)+"'.");			}			checkIndex(obj, obj.getClassIndex(), CONST_Class);			checkIndex(obj, obj.getNameAndTypeIndex(), CONST_NameAndType);		}		public void visitConstantString(ConstantString obj){			if (obj.getTag() != Constants.CONSTANT_String){				throw new ClassConstraintException("Wrong constant tag in '"+tostring(obj)+"'.");			}			checkIndex(obj, obj.getStringIndex(), CONST_Utf8);		}		public void visitConstantInteger(ConstantInteger obj){			if (obj.getTag() != Constants.CONSTANT_Integer){				throw new ClassConstraintException("Wrong constant tag in '"+tostring(obj)+"'.");			}			// no indices to check		}		public void visitConstantFloat(ConstantFloat obj){			if (obj.getTag() != Constants.CONSTANT_Float){				throw new ClassConstraintException("Wrong constant tag in '"+tostring(obj)+"'.");			}			//no indices to check		}		public void visitConstantLong(ConstantLong obj){			if (obj.getTag() != Constants.CONSTANT_Long){				throw new ClassConstraintException("Wrong constant tag in '"+tostring(obj)+"'.");			}			//no indices to check		}		public void visitConstantDouble(ConstantDouble obj){			if (obj.getTag() != Constants.CONSTANT_Double){				throw new ClassConstraintException("Wrong constant tag in '"+tostring(obj)+"'.");			}			//no indices to check		}		public void visitConstantNameAndType(ConstantNameAndType obj){			if (obj.getTag() != Constants.CONSTANT_NameAndType){				throw new ClassConstraintException("Wrong constant tag in '"+tostring(obj)+"'.");			}			checkIndex(obj, obj.getNameIndex(), CONST_Utf8);			//checkIndex(obj, obj.getDescriptorIndex(), CONST_Utf8); //inconsistently named in BCEL, see below.			checkIndex(obj, obj.getSignatureIndex(), CONST_Utf8);		}		public void visitConstantUtf8(ConstantUtf8 obj){			if (obj.getTag() != Constants.CONSTANT_Utf8){				throw new ClassConstraintException("Wrong constant tag in '"+tostring(obj)+"'.");			}			//no indices to check		}		//////////////////////////		// FIELDS (vmspec2 4.5) //		//////////////////////////		public void visitField(Field obj){			if (jc.isClass()){				int maxone=0;				if (obj.isPrivate()) maxone++;				if (obj.isProtected()) maxone++;				if (obj.isPublic()) maxone++;				if (maxone > 1){					throw new ClassConstraintException("Field '"+tostring(obj)+"' must only have at most one of its ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC modifiers set.");				}							if (obj.isFinal() && obj.isVolatile()){					throw new ClassConstraintException("Field '"+tostring(obj)+"' must only have at most one of its ACC_FINAL, ACC_VOLATILE modifiers set.");				}			}			else{ // isInterface!				if (!obj.isPublic()){					throw new ClassConstraintException("Interface field '"+tostring(obj)+"' must have the ACC_PUBLIC modifier set but hasn't!");				}				if (!obj.isStatic()){					throw new ClassConstraintException("Interface field '"+tostring(obj)+"' must have the ACC_STATIC modifier set but hasn't!");				}				if (!obj.isFinal()){					throw new ClassConstraintException("Interface field '"+tostring(obj)+"' must have the ACC_FINAL modifier set but hasn't!");				}			}			if ((obj.getAccessFlags() & ~(ACC_PUBLIC|ACC_PRIVATE|ACC_PROTECTED|ACC_STATIC|ACC_FINAL|ACC_VOLATILE|ACC_TRANSIENT)) > 0){				addMessage("Field '"+tostring(obj)+"' has access flag(s) other than ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_VOLATILE, ACC_TRANSIENT set (ignored).");			}			checkIndex(obj, obj.getNameIndex(), CONST_Utf8);						String name = obj.getName();			if (! validFieldName(name)){				throw new ClassConstraintException("Field '"+tostring(obj)+"' has illegal name '"+obj.getName()+"'.");			}			// A descriptor is often named signature in BCEL			checkIndex(obj, obj.getSignatureIndex(), CONST_Utf8);						String sig  = ((ConstantUtf8) (cp.getConstant(obj.getSignatureIndex()))).getBytes(); // Field or Method signature(=descriptor)			try{				Type t = Type.getType(sig);			}			catch (ClassFormatError cfe){ // sometimes BCEL is a little harsh describing exceptional situations.				throw new ClassConstraintException("Illegal descriptor (==signature) '"+sig+"' used by '"+tostring(obj)+"'.");			}						String nameanddesc = (name+sig);			if (field_names_and_desc.contains(nameanddesc)){				throw new ClassConstraintException("No two fields (like '"+tostring(obj)+"') are allowed have same names and descriptors!");			}			if (field_names.contains(name)){				addMessage("More than one field of name '"+name+"' detected (but with different type descriptors). This is very unusual.");			}			field_names_and_desc.add(nameanddesc);			field_names.add(name);						Attribute[] atts = obj.getAttributes();			for (int i=0; i<atts.length; i++){				if ((! (atts[i] instanceof ConstantValue)) &&				    (! (atts[i] instanceof Synthetic))     &&				    (! (atts[i] instanceof Deprecated))){					addMessage("Attribute '"+tostring(atts[i])+"' as an attribute of Field '"+tostring(obj)+"' is unknown and will therefore be ignored.");				}				if  (! (atts[i] instanceof ConstantValue)){					addMessage("Attribute '"+tostring(atts[i])+"' as an attribute of Field '"+tostring(obj)+"' is not a ConstantValue and is therefore only of use for debuggers and such.");				}			}		}		///////////////////////////		// METHODS (vmspec2 4.6) //		///////////////////////////		public void visitMethod(Method obj){			checkIndex(obj, obj.getNameIndex(), CONST_Utf8);						String name = obj.getName();			if (! validMethodName(name, true)){				throw new ClassConstraintException("Method '"+tostring(obj)+"' has illegal name '"+name+"'.");			}			// A descriptor is often named signature in BCEL			checkIndex(obj, obj.getSignatureIndex(), CONST_Utf8);			String sig  = ((ConstantUtf8) (cp.getConstant(obj.getSignatureIndex()))).getBytes(); // Method's signature(=descriptor)				Type t;			Type[] ts; // needed below the try block.			try{				t  = Type.getReturnType(sig);				ts = Type.getArgumentTypes(sig);			}			catch (ClassFormatError cfe){				// Well, BCEL sometimes is a little harsh describing exceptional situations.				throw new ClassConstraintException("Illegal descriptor (==signature) '"+sig+"' used by Method '"+tostring(obj)+"'.");			}			// Check if referenced objects exist.			Type act = t;			if (act instanceof ArrayType) act = ((ArrayType) act).getBasicType();			if (act instanceof ObjectType){				Verifier v = VerifierFactory.getVerifier( ((ObjectType) act).getClassName() );				VerificationResult vr = v.doPass1();				if (vr != VerificationResult.VR_OK) {					throw new ClassConstraintException("Method '"+tostring(obj)+"' has a return type that does not pass verification pass 1: '"+vr+"'.");				}			}						for (int i=0; i<ts.length; i++){				act = ts[i];				if (act instanceof ArrayType) act = ((ArrayType) act).getBasicType();				if (act instanceof ObjectType){					Verifier v = VerifierFactory.getVerifier( ((ObjectType) act).getClassName() );					VerificationResult vr = v.doPass1();					if (vr != VerificationResult.VR_OK) {						throw new ClassConstraintException("Method '"+tostring(obj)+"' has an argument type that does not pass verification pass 1: '"+vr+"'.");					}				}			}			// Nearly forgot this! Funny return values are allowed, but a non-empty arguments list makes a different method out of it!			if (name.equals(STATIC_INITIALIZER_NAME) && (ts.length != 0)){				throw new ClassConstraintException("Method '"+tostring(obj)+"' has illegal name '"+name+"'. It's name resembles the class or interface initialization method which it isn't because of its arguments (==descriptor).");			}			if (jc.isClass()){				int maxone=0;				if (obj.isPrivate()) maxone++;				if (obj.isProtected()) maxone++;				if (obj.isPublic()) maxone++;				if (maxone > 1){					throw new ClassConstraintException("Method '"+tostring(obj)+"' must only have at most one of its ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC modifiers set.");				}							if (obj.isAbstract()){					if (obj.isFinal()) throw new ClassConstraintException("Abstract method '"+tostring(obj)+"' must not have the ACC_FINAL modifier set.");					if (obj.isNative()) throw new ClassConstraintException("Abstract method '"+tostring(obj)+"' must not have the ACC_NATIVE modifier set.");					if (obj.isPrivate()) throw new ClassConstraintException("Abstract method '"+tostring(obj)+"' must not have the ACC_PRIVATE modifier set.");					if (obj.isStatic()) throw new ClassConstraintException("Abstract method '"+tostring(obj)+"' must not have the ACC_STATIC modifier set.");					if (obj.isStrictfp()) throw new ClassConstraintException("Abstract method '"+tostring(obj)+"' must not have the ACC_STRICT modifier set.");					if (obj.isSynchronized()) throw new ClassConstraintException("Abstract method '"+tostring(obj)+"' must not have the ACC_SYNCHRONIZED modifier set.");				}			}			else{ // isInterface!				if (!name.equals(STATIC_INITIALIZER_NAME)){//vmspec2, p.116, 2nd paragraph					if (!obj.isPublic()){						throw new ClassConstraintException("Interface method '"+tostring(obj)+"' must have the ACC_PUBLIC modifier set but hasn't!");					}					if (!obj.isAbstract()){						throw new ClassConstraintException("Interface method '"+tostring(obj)+"' must have the ACC_STATIC modifier set but hasn't!");					}					if (	obj.isPrivate() ||								obj.isProtected() ||								obj.isStatic() ||								obj.isFinal() ||								obj.isSynchronized() ||								obj.isNative() ||								obj.isStrictfp() ){						throw new ClassConstraintException("Interface method '"+tostring(obj)+"' must not have any of the ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT, ACC_STRICT modifiers set.");					}				}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -