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

📄 pass2verifier.java

📁 该开源工具主要用于class文件的操作
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
			}			// A specific instance initialization method... (vmspec2,Page 116).			if (name.equals(CONSTRUCTOR_NAME)){				//..may have at most one of ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC set: is checked above.				//..may also have ACC_STRICT set, but none of the other flags in table 4.5 (vmspec2, page 115)				if (	obj.isStatic() ||							obj.isFinal() ||							obj.isSynchronized() ||							obj.isNative() ||							obj.isAbstract() ){					throw new ClassConstraintException("Instance initialization method '"+tostring(obj)+"' must not have any of the ACC_STATIC, ACC_FINAL, ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT modifiers set.");				}			}			// Class and interface initialization methods...			if (name.equals(STATIC_INITIALIZER_NAME)){				if ((obj.getAccessFlags() & (~ACC_STRICT)) > 0){					addMessage("Class or interface initialization method '"+tostring(obj)+"' has superfluous access modifier(s) set: everything but ACC_STRICT is ignored.");				}				if (obj.isAbstract()){					throw new ClassConstraintException("Class or interface initialization method '"+tostring(obj)+"' must not be abstract. This contradicts the Java Language Specification, Second Edition (which omits this constraint) but is common practice of existing verifiers.");				}			}			if ((obj.getAccessFlags() & ~(ACC_PUBLIC|ACC_PRIVATE|ACC_PROTECTED|ACC_STATIC|ACC_FINAL|ACC_SYNCHRONIZED|ACC_NATIVE|ACC_ABSTRACT|ACC_STRICT)) > 0){				addMessage("Method '"+tostring(obj)+"' has access flag(s) other than ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT, ACC_STRICT set (ignored).");			}			String nameanddesc = (name+sig);			if (method_names_and_desc.contains(nameanddesc)){				throw new ClassConstraintException("No two methods (like '"+tostring(obj)+"') are allowed have same names and desciptors!");			}			method_names_and_desc.add(nameanddesc);			Attribute[] atts = obj.getAttributes();			int num_code_atts = 0;			for (int i=0; i<atts.length; i++){				if ((! (atts[i] instanceof Code)) &&				    (! (atts[i] instanceof ExceptionTable))     &&				    (! (atts[i] instanceof Synthetic)) &&				    (! (atts[i] instanceof Deprecated))){					addMessage("Attribute '"+tostring(atts[i])+"' as an attribute of Method '"+tostring(obj)+"' is unknown and will therefore be ignored.");				}				if ((! (atts[i] instanceof Code)) &&						(! (atts[i] instanceof ExceptionTable))){					addMessage("Attribute '"+tostring(atts[i])+"' as an attribute of Method '"+tostring(obj)+"' is neither Code nor Exceptions and is therefore only of use for debuggers and such.");				}				if ((atts[i] instanceof Code) && (obj.isNative() || obj.isAbstract())){					throw new ClassConstraintException("Native or abstract methods like '"+tostring(obj)+"' must not have a Code attribute like '"+tostring(atts[i])+"'."); //vmspec2 page120, 4.7.3				}				if (atts[i] instanceof Code) num_code_atts++;			}			if ( !obj.isNative() && !obj.isAbstract() && num_code_atts != 1){				throw new ClassConstraintException("Non-native, non-abstract methods like '"+tostring(obj)+"' must have exactly one Code attribute (found: "+num_code_atts+").");			}		}		///////////////////////////////////////////////////////		// ClassFile-structure-ATTRIBUTES (vmspec2 4.1, 4.7) //		///////////////////////////////////////////////////////		public void visitSourceFile(SourceFile obj){//vmspec2 4.7.7			// zero or one SourceFile attr per ClassFile: see visitJavaClass()			checkIndex(obj, obj.getNameIndex(), CONST_Utf8);						String name = ((ConstantUtf8) cp.getConstant(obj.getNameIndex())).getBytes();			if (! name.equals("SourceFile")){				throw new ClassConstraintException("The SourceFile attribute '"+tostring(obj)+"' is not correctly named 'SourceFile' but '"+name+"'.");			}			checkIndex(obj, obj.getSourceFileIndex(), CONST_Utf8);						String sourcefilename = ((ConstantUtf8) cp.getConstant(obj.getSourceFileIndex())).getBytes(); //==obj.getSourceFileName() ?			String sourcefilenamelc = sourcefilename.toLowerCase();			if (	(sourcefilename.indexOf('/') != -1) ||						(sourcefilename.indexOf('\\') != -1) ||						(sourcefilename.indexOf(':') != -1) ||						(sourcefilenamelc.lastIndexOf(".java") == -1)	){				addMessage("SourceFile attribute '"+tostring(obj)+"' has a funny name: remember not to confuse certain parsers working on javap's output. Also, this name ('"+sourcefilename+"') is considered an unqualified (simple) file name only.");			}		}		public void visitDeprecated(Deprecated obj){//vmspec2 4.7.10			checkIndex(obj, obj.getNameIndex(), CONST_Utf8);			String name = ((ConstantUtf8) cp.getConstant(obj.getNameIndex())).getBytes();			if (! name.equals("Deprecated")){				throw new ClassConstraintException("The Deprecated attribute '"+tostring(obj)+"' is not correctly named 'Deprecated' but '"+name+"'.");			}		}		public void visitSynthetic(Synthetic obj){//vmspec2 4.7.6			checkIndex(obj, obj.getNameIndex(), CONST_Utf8);			String name = ((ConstantUtf8) cp.getConstant(obj.getNameIndex())).getBytes();			if (! name.equals("Synthetic")){				throw new ClassConstraintException("The Synthetic attribute '"+tostring(obj)+"' is not correctly named 'Synthetic' but '"+name+"'.");			}		}		public void visitInnerClasses(InnerClasses obj){//vmspec2 4.7.5			// exactly one InnerClasses attr per ClassFile if some inner class is refernced: see visitJavaClass()					checkIndex(obj, obj.getNameIndex(), CONST_Utf8);			String name = ((ConstantUtf8) cp.getConstant(obj.getNameIndex())).getBytes();			if (! name.equals("InnerClasses")){				throw new ClassConstraintException("The InnerClasses attribute '"+tostring(obj)+"' is not correctly named 'InnerClasses' but '"+name+"'.");			}			InnerClass[] ics = obj.getInnerClasses();						for (int i=0; i<ics.length; i++){				checkIndex(obj, ics[i].getInnerClassIndex(), CONST_Class);				int outer_idx = ics[i].getOuterClassIndex();				if (outer_idx != 0){					checkIndex(obj, outer_idx, CONST_Class);				}				int innername_idx = ics[i].getInnerNameIndex();				if (innername_idx != 0){					checkIndex(obj, innername_idx, CONST_Utf8);				}				int acc = ics[i].getInnerAccessFlags();				acc = acc & (~ (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC | ACC_FINAL | ACC_INTERFACE | ACC_ABSTRACT));				if (acc != 0){					addMessage("Unknown access flag for inner class '"+tostring(ics[i])+"' set (InnerClasses attribute '"+tostring(obj)+"').");				}			}			// Semantical consistency is not yet checked by Sun, see vmspec2 4.7.5.			// [marked TODO in JustIce]		}		////////////////////////////////////////////////////////		// field_info-structure-ATTRIBUTES (vmspec2 4.5, 4.7) //		////////////////////////////////////////////////////////		public void visitConstantValue(ConstantValue obj){//vmspec2 4.7.2			// Despite its name, this really is an Attribute,			// not a constant!			checkIndex(obj, obj.getNameIndex(), CONST_Utf8);			String name = ((ConstantUtf8) cp.getConstant(obj.getNameIndex())).getBytes();			if (! name.equals("ConstantValue")){				throw new ClassConstraintException("The ConstantValue attribute '"+tostring(obj)+"' is not correctly named 'ConstantValue' but '"+name+"'.");			}			Object pred = carrier.predecessor();			if (pred instanceof Field){ //ConstantValue attributes are quite senseless if the predecessor is not a field.				Field f = (Field) pred;				// Field constraints have been checked before -- so we are safe using their type information.				Type field_type = Type.getType(((ConstantUtf8) (cp.getConstant(f.getSignatureIndex()))).getBytes());				int index = obj.getConstantValueIndex();				if ((index < 0) || (index >= cplen)){					throw new ClassConstraintException("Invalid index '"+index+"' used by '"+tostring(obj)+"'.");				}				Constant c = cp.getConstant(index);								if (CONST_Long.isInstance(c) && field_type.equals(Type.LONG)){					return;				}				if (CONST_Float.isInstance(c) && field_type.equals(Type.FLOAT)){					return;				}				if (CONST_Double.isInstance(c) && field_type.equals(Type.DOUBLE)){					return;				}				if (CONST_Integer.isInstance(c) && (field_type.equals(Type.INT) || field_type.equals(Type.SHORT) || field_type.equals(Type.CHAR) || field_type.equals(Type.BYTE) || field_type.equals(Type.BOOLEAN))){					return;				}				if (CONST_String.isInstance(c) && field_type.equals(Type.STRING)){					return;				}												throw new ClassConstraintException("Illegal type of ConstantValue '"+obj+"' embedding Constant '"+c+"'. It is referenced by field '"+tostring(f)+"' expecting a different type: '"+field_type+"'.");			}		}		// SYNTHETIC: see above		// DEPRECATED: see above		/////////////////////////////////////////////////////////		// method_info-structure-ATTRIBUTES (vmspec2 4.6, 4.7) //		/////////////////////////////////////////////////////////		public void visitCode(Code obj){//vmspec2 4.7.3			// No code attribute allowed for native or abstract methods: see visitMethod(Method).			// Code array constraints are checked in Pass3 (3a and 3b).			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;					int max_locals = code.getMaxLocals();					//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();

⌨️ 快捷键说明

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