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

📄 pass2verifier.java

📁 该开源工具主要用于class文件的操作
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
package org.apache.bcel.verifier.statics;/* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2001 The Apache Software Foundation.  All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in *    the documentation and/or other materials provided with the *    distribution. * * 3. The end-user documentation included with the redistribution, *    if any, must include the following acknowledgment: *       "This product includes software developed by the *        Apache Software Foundation (http://www.apache.org/)." *    Alternately, this acknowledgment may appear in the software itself, *    if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" and *    "Apache BCEL" must not be used to endorse or promote products *    derived from this software without prior written permission. For *    written permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache", *    "Apache BCEL", nor may "Apache" appear in their name, without *    prior written permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation.  For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */import org.apache.bcel.Constants;import org.apache.bcel.Repository;import org.apache.bcel.classfile.*;import org.apache.bcel.classfile.DescendingVisitor; // Use _this_ one!import org.apache.bcel.classfile.EmptyVisitor; // Use _this_ one!import org.apache.bcel.classfile.Visitor; // Use _this_ one!import org.apache.bcel.generic.*;import org.apache.bcel.verifier.*;import org.apache.bcel.verifier.exc.*;import java.util.HashMap;import java.util.HashSet;/** * This PassVerifier verifies a class file according to * pass 2 as described in The Java Virtual Machine * Specification, 2nd edition. * More detailed information is to be found at the do_verify() * method's documentation. * * @version $Id: Pass2Verifier.java,v 1.1.1.1 2001/10/29 20:00:36 jvanzyl Exp $ * @author <A HREF="http://www.inf.fu-berlin.de/~ehaase"/>Enver Haase</A> * @see #do_verify() */public final class Pass2Verifier extends PassVerifier implements Constants{	/**	 * The LocalVariableInfo instances used by Pass3bVerifier.	 * localVariablesInfos[i] denotes the information for the	 * local variables of method number i in the	 * JavaClass this verifier operates on.	 */	private LocalVariablesInfo[] localVariablesInfos;		/** The Verifier that created this. */	private Verifier myOwner;	/**	 * Should only be instantiated by a Verifier.	 *	 * @see Verifier	 */	public Pass2Verifier(Verifier owner){		myOwner = owner;	}	/**	 * Returns a LocalVariablesInfo object containing information	 * about the usage of the local variables in the Code attribute	 * of the said method or <B>null</B> if the class file this	 * Pass2Verifier operates on could not be pass-2-verified correctly.	 * The method number method_nr is the method you get using	 * <B>Repository.lookupClass(myOwner.getClassname()).getMethods()[method_nr];</B>.	 * You should not add own information. Leave that to JustIce.	 */	public LocalVariablesInfo getLocalVariablesInfo(int method_nr){		if (this.verify() != VerificationResult.VR_OK) return null; // It's cached, don't worry.		if (method_nr < 0 || method_nr >= localVariablesInfos.length){			throw new AssertionViolatedException("Method number out of range.");		}		return localVariablesInfos[method_nr];	}		/**	 * Pass 2 is the pass where static properties of the	 * class file are checked without looking into "Code"	 * arrays of methods.	 * This verification pass is usually invoked when	 * a class is resolved; and it may be possible that	 * this verification pass has to load in other classes	 * such as superclasses or implemented interfaces.	 * Therefore, Pass 1 is run on them.<BR>	 * Note that most referenced classes are <B>not</B> loaded	 * in for verification or for an existance check by this	 * pass; only the syntactical correctness of their names	 * and descriptors (a.k.a. signatures) is checked.<BR>	 * Very few checks that conceptually belong here	 * are delayed until pass 3a in JustIce. JustIce does	 * not only check for syntactical correctness but also	 * for semantical sanity - therefore it needs access to	 * the "Code" array of methods in a few cases. Please	 * see the pass 3a documentation, too.	 *	 * @see org.apache.bcel.verifier.statics.Pass3aVerifier	 */	public VerificationResult do_verify(){		VerificationResult vr1 = myOwner.doPass1();		if (vr1.equals(VerificationResult.VR_OK)){						// For every method, we could have information about the local variables out of LocalVariableTable attributes of			// the Code attributes.			localVariablesInfos = new LocalVariablesInfo[Repository.lookupClass(myOwner.getClassName()).getMethods().length];			VerificationResult vr = VerificationResult.VR_OK; // default.			try{				constant_pool_entries_satisfy_static_constraints();				field_and_method_refs_are_valid();				every_class_has_an_accessible_superclass();				final_methods_are_not_overridden();			}			catch (ClassConstraintException cce){				vr = new VerificationResult(VerificationResult.VERIFIED_REJECTED, cce.getMessage());			}			return vr;		}		else			return VerificationResult.VR_NOTYET;	}	/**	 * Ensures that every class has a super class and that	 * <B>final</B> classes are not subclassed.	 * This means, the class this Pass2Verifier operates	 * on has proper super classes (transitively) up to	 * java.lang.Object.	 * The reason for really loading (and Pass1-verifying)	 * all of those classes here is that we need them in	 * Pass2 anyway to verify no final methods are overridden	 * (that could be declared anywhere in the ancestor hierarchy).	 *	 * @throws ClassConstraintException otherwise.	 */	private void every_class_has_an_accessible_superclass(){		HashSet hs = new HashSet(); // save class names to detect circular inheritance		JavaClass jc = Repository.lookupClass(myOwner.getClassName());		int supidx = -1;		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.");				}			}		}	}	/**	 * Ensures that <B>final</B> methods are not overridden.	 * <B>Precondition to run this method:	 * constant_pool_entries_satisfy_static_constraints() and	 * every_class_has_an_accessible_superclass() have to be invoked before	 * (in that order).</B>	 *	 * @throws ClassConstraintException otherwise.	 * @see #constant_pool_entries_satisfy_static_constraints()	 * @see #every_class_has_an_accessible_superclass()	 */	private void final_methods_are_not_overridden(){		HashMap hashmap = new HashMap();		JavaClass jc = Repository.lookupClass(myOwner.getClassName());				int supidx = -1;		while (supidx != 0){			supidx = jc.getSuperclassNameIndex();			ConstantPoolGen cpg = new ConstantPoolGen(jc.getConstantPool());			Method[] methods = jc.getMethods();			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());						}					}				}				else{					if (!methods[i].isStatic()){ // static methods don't inherit						hashmap.put(name_and_sig, jc.getClassName());					}				}			}					jc = Repository.lookupClass(jc.getSuperclassName());	// Well, for OBJECT this returns OBJECT so it works (could return anything but must not throw an Exception).		}	}	/**	 * Ensures that the constant pool entries satisfy the static constraints	 * as described in The Java Virtual Machine Specification, 2nd Edition.	 *	 * @throws ClassConstraintException otherwise.	 */	private void constant_pool_entries_satisfy_static_constraints(){		// Most of the consistency is handled internally by BCEL; here		// we only have to verify if the indices of the constants point		// to constants of the appropriate type and such.		JavaClass jc = Repository.lookupClass(myOwner.getClassName());		new CPESSC_Visitor(jc); // constructor implicitely traverses jc	}	/**	 * A Visitor class that ensures the constant pool satisfies the static	 * constraints.   * The visitXXX() methods throw ClassConstraintException instances otherwise.   *   * @see #constant_pool_entries_satisfy_static_constraints()	 */	private class CPESSC_Visitor extends org.apache.bcel.classfile.EmptyVisitor implements Visitor{		private Class CONST_Class;		private Class CONST_Fieldref;		private Class CONST_Methodref;		private Class CONST_InterfaceMethodref;		private Class CONST_String;		private Class CONST_Integer;		private Class CONST_Float;		private Class CONST_Long;		private Class CONST_Double;		private Class CONST_NameAndType;		private Class CONST_Utf8;		private final JavaClass jc;		private final ConstantPool cp; // ==jc.getConstantPool() -- only here to save typing work and computing power.		private final int cplen; // == cp.getLength() -- to save computing power.		private DescendingVisitor carrier;		private HashSet field_names = new HashSet();		private HashSet field_names_and_desc = new HashSet();		private HashSet method_names_and_desc = new HashSet();				private CPESSC_Visitor(JavaClass _jc){			jc = _jc;			cp = _jc.getConstantPool();			cplen = cp.getLength();						CONST_Class = org.apache.bcel.classfile.ConstantClass.class;			CONST_Fieldref = org.apache.bcel.classfile.ConstantFieldref.class;			CONST_Methodref = org.apache.bcel.classfile.ConstantMethodref.class;			CONST_InterfaceMethodref = org.apache.bcel.classfile.ConstantInterfaceMethodref.class;			CONST_String = org.apache.bcel.classfile.ConstantString.class;

⌨️ 快捷键说明

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