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 * . */ import org.apache.bcel.classfile.*; import org.apache.bcel.Repository; import org.apache.bcel.verifier.*; import org.apache.bcel.verifier.exc.*; import org.apache.bcel.verifier.exc.Utility; import java.util.ArrayList; /** * This PassVerifier verifies a class file according to pass 1 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$ * @author Enver Haase * @see #do_verify() */ public final class Pass1Verifier extends PassVerifier{ /** * DON'T USE THIS EVEN PRIVATELY! USE getJavaClass() INSTEAD. * @see #getJavaClass() */ private JavaClass jc; /** * The Verifier that created this. */ private Verifier myOwner; /** Used to load in and return the myOwner-matching JavaClass object when needed. Avoids loading in a class file when it's not really needed! */ private JavaClass getJavaClass(){ if (jc == null){ jc = Repository.lookupClass(myOwner.getClassName()); } return jc; } /** * Should only be instantiated by a Verifier. * * @see org.apache.bcel.verifier.Verifier */ public Pass1Verifier(Verifier owner){ myOwner = owner; } /** * Pass-one verification basically means loading in a class file. * The Java Virtual Machine Specification is not too precise about * what makes the difference between passes one and two. * The answer is that only pass one is performed on a class file as * long as its resolution is not requested; whereas pass two and * pass three are performed during the resolution process. * Only four constraints to be checked are explicitely stated by * The Java Virtual Machine Specification, 2nd edition: * * A more in-depth documentation of what pass one should do was written by * Philip W. L. Fong: * * (From the Paper The Mysterious Pass One, first draft, September 2, 1997.) *
* However, most of this is done by parsing a class file or generating a class file into BCEL's internal data structure. * Therefore, all that is really done here is look up the class file from BCEL's repository. * This is also motivated by the fact that some omitted things * (like the check for extra bytes at the end of the class file) are handy when actually using BCEL to repair a class file (otherwise you would not be * able to load it into BCEL). * * @see org.apache.bcel.Repository */ public VerificationResult do_verify(){ JavaClass jc; try{ jc = getJavaClass(); //loads in the class file if not already done. if (jc != null){ /* If we find more constraints to check, we should do this in an own method. */ if (! myOwner.getClassName().equals(jc.getClassName())){ // This should maybe caught by BCEL: In case of renamed .class files we get wrong // JavaClass objects here. throw new LoadingException("Wrong name: the internal name of the .class file '"+jc.getClassName()+"' does not match the file's name '"+myOwner.getClassName()+"'."); } } } catch(LoadingException e){ return new VerificationResult(VerificationResult.VERIFIED_REJECTED, e.getMessage()); } catch(ClassFormatError e){ // BCEL sometimes is a little harsh describing exceptual situations. return new VerificationResult(VerificationResult.VERIFIED_REJECTED, e.getMessage()); } catch(RuntimeException e){ // BCEL does not catch every possible RuntimeException; e.g. if // a constant pool index is referenced that does not exist. return new VerificationResult(VerificationResult.VERIFIED_REJECTED, "Parsing via BCEL did not succeed. "+e.getClass().getName()+" occured:\n"+Utility.getStackTrace(e)); } if (jc != null){ return VerificationResult.VR_OK; } else{ //TODO: Maybe change Repository's behaviour to throw a LoadingException instead of just returning "null" // if a class file cannot be found or in another way be looked up. return new VerificationResult(VerificationResult.VERIFIED_REJECTED, "Repository.lookup() failed. FILE NOT FOUND?"); } } /** * Currently this returns an empty array of String. * One could parse the error messages of BCEL * (written to java.lang.System.err) when loading * a class file such as detecting unknown attributes * or trailing garbage at the end of a class file. * However, Markus Dahm does not like the idea so this * method is currently useless and therefore marked as * TODO. */ public String[] getMessages(){ // This method is only here to override the javadoc-comment. return super.getMessages(); } }