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

📄 pass2verifier.java

📁 该开源工具主要用于class文件的操作
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
						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				public void visitExceptionTable(ExceptionTable obj){//vmspec2 4.7.4			// 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()+"'.");				}			}		}		// SYNTHETIC: see above		// DEPRECATED: see above		//////////////////////////////////////////////////////////////		// code_attribute-structure-ATTRIBUTES (vmspec2 4.7.3, 4.7) //		//////////////////////////////////////////////////////////////		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...		}		public void visitLocalVariableTable(LocalVariableTable obj){//vmspec2 4.7.9			//In JustIce,this check is partially delayed to Pass 3a.			//The other part can be found in the visitCode(Code) method.		}		////////////////////////////////////////////////////		// MISC-structure-ATTRIBUTES (vmspec2 4.7.1, 4.7) //		////////////////////////////////////////////////////		public void visitUnknown(Unknown obj){//vmspec2 4.7.1			// Represents an unknown attribute.			checkIndex(obj, obj.getNameIndex(), CONST_Utf8);						// Maybe only misnamed? Give a (warning) message.			addMessage("Unknown attribute '"+tostring(obj)+"'. This attribute is not known in any context!");		}		//////////		// BCEL //		//////////		public void visitLocalVariable(LocalVariable obj){			// This does not represent an Attribute but is only			// related to internal BCEL data representation.			// see visitLocalVariableTable(LocalVariableTable)		}		public void visitCodeException(CodeException obj){			// Code constraints are checked in Pass3 (3a and 3b).			// This does not represent an Attribute but is only			// related to internal BCEL data representation.					// see visitCode(Code)		}		public void visitConstantPool(ConstantPool obj){			// No need to. We're piggybacked by the DescendingVisitor.			// This does not represent an Attribute but is only			// related to internal BCEL data representation.		}		public void visitInnerClass(InnerClass obj){			// This does not represent an Attribute but is only			// related to internal BCEL data representation.		}		public void visitLineNumber(LineNumber obj){			// This does not represent an Attribute but is only			// related to internal BCEL data representation.			// see visitLineNumberTable(LineNumberTable)		}	}	/**	 * Ensures that the ConstantCP-subclassed entries of the constant	 * pool are valid. According to "Yellin: Low Level Security in Java",	 * this method does not verify the existence of referenced entities	 * (such as classes) but only the formal correctness (such as well-formed	 * signatures).   * The visitXXX() methods throw ClassConstraintException instances otherwise.	 * <B>Precondition: index-style cross referencing in the constant	 * pool must be valid. Simply invoke constant_pool_entries_satisfy_static_constraints()	 * before.</B>	 *	 * @throws ClassConstraintException otherwise.	 * @see #constant_pool_entries_satisfy_static_constraints()	 */	private void field_and_method_refs_are_valid(){		JavaClass jc = Repository.lookupClass(myOwner.getClassName());		DescendingVisitor v = new DescendingVisitor(jc, new FAMRAV_Visitor(jc));		v.visit();	}	/**	 * A Visitor class that ensures the ConstantCP-subclassed entries	 * of the constant pool are valid.   * <B>Precondition: index-style cross referencing in the constant   * pool must be valid.</B>	 *   * @see #constant_pool_entries_satisfy_static_constraints()	 * @see org.apache.bcel.classfile.ConstantCP	 */	private class FAMRAV_Visitor extends EmptyVisitor implements Visitor{		private final JavaClass jc;		private final ConstantPool cp; // ==jc.getConstantPool() -- only here to save typing work.		private FAMRAV_Visitor(JavaClass _jc){			jc = _jc;			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 t = Type.getType(sig);			}			catch (ClassFormatError cfe){				// Well, BCEL sometimes is a little harsh describing exceptional situations.				throw new ClassConstraintException("Illegal descriptor (==signature) '"+sig+"' used by '"+tostring(obj)+"'.");			}		}		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);				Type[] ts = Type.getArgumentTypes(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)+"'.");			}		}		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);				Type[] ts = Type.getArgumentTypes(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)+"'.");			}		}			}	/**	 * This method returns true if and only if the supplied String	 * represents a valid Java class name.	 */	private static final boolean validClassName(String name){		// Are there restrictions?		return true;	}	/**	 * This method returns true if and only if the supplied String	 * represents a valid method name.	 * This is basically the same as a valid identifier name in the	 * Java programming language, but the special name for	 * the instance initialization method is allowed and the special name	 * for the class/interface initialization method may be allowed.	 */	private static boolean validMethodName(String name, boolean allowStaticInit){		if (validJavaLangMethodName(name)) return true;				if (allowStaticInit){			return (name.equals(CONSTRUCTOR_NAME) || name.equals(STATIC_INITIALIZER_NAME));		}		else{			return name.equals(CONSTRUCTOR_NAME);		}	}	/**	 * This method returns true if and only if the supplied String	 * represents a valid method name that may be referenced by	 * ConstantMethodref objects.	 */	private static boolean validClassMethodName(String name){		return validMethodName(name, false);	}	/**	 * This method returns true if and only if the supplied String	 * represents a valid Java programming language method name stored as a simple	 * (non-qualified) name.	 * Conforming to: The Java Virtual Machine Specification, Second Edition, 

⌨️ 快捷键说明

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