1   package org.apache.bcel.verifier;
2   
3   /* ====================================================================
4    * The Apache Software License, Version 1.1
5    *
6    * Copyright (c) 2001 The Apache Software Foundation.  All rights
7    * reserved.
8    *
9    * Redistribution and use in source and binary forms, with or without
10   * modification, are permitted provided that the following conditions
11   * are met:
12   *
13   * 1. Redistributions of source code must retain the above copyright
14   *    notice, this list of conditions and the following disclaimer.
15   *
16   * 2. Redistributions in binary form must reproduce the above copyright
17   *    notice, this list of conditions and the following disclaimer in
18   *    the documentation and/or other materials provided with the
19   *    distribution.
20   *
21   * 3. The end-user documentation included with the redistribution,
22   *    if any, must include the following acknowledgment:
23   *       "This product includes software developed by the
24   *        Apache Software Foundation (http://www.apache.org/)."
25   *    Alternately, this acknowledgment may appear in the software itself,
26   *    if and wherever such third-party acknowledgments normally appear.
27   *
28   * 4. The names "Apache" and "Apache Software Foundation" and
29   *    "Apache BCEL" must not be used to endorse or promote products
30   *    derived from this software without prior written permission. For
31   *    written permission, please contact apache@apache.org.
32   *
33   * 5. Products derived from this software may not be called "Apache",
34   *    "Apache BCEL", nor may "Apache" appear in their name, without
35   *    prior written permission of the Apache Software Foundation.
36   *
37   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
41   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48   * SUCH DAMAGE.
49   * ====================================================================
50   *
51   * This software consists of voluntary contributions made by many
52   * individuals on behalf of the Apache Software Foundation.  For more
53   * information on the Apache Software Foundation, please see
54   * <http://www.apache.org/>.
55   */
56  
57  import org.apache.bcel.*;
58  import org.apache.bcel.classfile.*;
59  import org.apache.bcel.verifier.statics.*;
60  import org.apache.bcel.verifier.structurals.*;
61  import java.util.ArrayList;
62  import java.util.HashMap;
63  import java.util.Iterator;
64  
65  /***
66   * A Verifier instance is there to verify a class file according to The Java Virtual
67   * Machine Specification, 2nd Edition.
68   *
69   * Pass-3b-verification includes pass-3a-verification;
70   * pass-3a-verification includes pass-2-verification;
71   * pass-2-verification includes pass-1-verification.
72   *
73   * A Verifier creates PassVerifier instances to perform the actual verification.
74   * Verifier instances are usually generated by the VerifierFactory.
75   *
76   * @version $Id: Verifier.java,v 1.7 2002/10/13 21:56:16 enver Exp $
77   * @author <A HREF="http://www.inf.fu-berlin.de/~ehaase"/>Enver Haase</A>
78   * @see org.apache.bcel.verifier.VerifierFactory
79   * @see org.apache.bcel.verifier.PassVerifier
80   */
81  public class Verifier{
82  	/***
83  	 * The name of the class this verifier operates on.
84  	 */
85  	private final String classname;
86  
87  	/*** A Pass1Verifier for this Verifier instance. */
88  	private Pass1Verifier p1v;
89  	/*** A Pass2Verifier for this Verifier instance. */
90  	private Pass2Verifier p2v;
91  	/*** The Pass3aVerifiers for this Verifier instance. Key: Interned string specifying the method number. */
92  	private HashMap p3avs = new HashMap();
93  	/*** The Pass3bVerifiers for this Verifier instance. Key: Interned string specifying the method number. */
94  	private HashMap p3bvs = new HashMap();
95  
96  	/*** Returns the VerificationResult for the given pass. */
97  	public VerificationResult doPass1(){
98  		if (p1v == null){
99  			p1v = new Pass1Verifier(this);
100 		}
101 		return p1v.verify();
102 	}
103 
104 	/*** Returns the VerificationResult for the given pass. */
105 	public VerificationResult doPass2(){
106 		if (p2v == null){
107 			p2v = new Pass2Verifier(this);
108 		}
109 		return p2v.verify();
110 	}
111 
112 	/*** Returns the VerificationResult for the given pass. */
113 	public VerificationResult doPass3a(int method_no){
114 		String key = Integer.toString(method_no);
115 		Pass3aVerifier p3av;
116 		p3av = (Pass3aVerifier) (p3avs.get(key));
117 		if (p3avs.get(key) == null){
118 			p3av = new Pass3aVerifier(this, method_no);
119 			p3avs.put(key, p3av);
120 		}
121 		return p3av.verify();
122 	}
123 
124 	/*** Returns the VerificationResult for the given pass. */
125 	public VerificationResult doPass3b(int method_no){
126 		String key = Integer.toString(method_no);
127 		Pass3bVerifier p3bv;
128 		p3bv = (Pass3bVerifier) (p3bvs.get(key));
129 		if (p3bvs.get(key) == null){
130 			p3bv = new Pass3bVerifier(this, method_no);
131 			p3bvs.put(key, p3bv);
132 		}
133 		return p3bv.verify();
134 	}
135 
136 
137 	/***
138 	 * Instantiation is done by the VerifierFactory.
139 	 *
140 	 * @see VerifierFactory
141 	 */
142 	Verifier(String fully_qualified_classname){
143 		classname = fully_qualified_classname;
144 		flush();
145 	}
146 
147 	/***
148 	 * Returns the name of the class this verifier operates on.
149 	 * This is particularly interesting when this verifier was created
150 	 * recursively by another Verifier and you got a reference to this
151 	 * Verifier by the getVerifiers() method of the VerifierFactory.
152 	 * @see VerifierFactory
153 	 */
154 	public final String getClassName(){
155 		return classname;
156 	}
157 
158 	/***
159 	 * Forget everything known about the class file; that means, really
160 	 * start a new verification of a possibly different class file from
161 	 * BCEL's repository.
162 	 *
163 	 */
164 	public void flush(){
165 		p1v = null;
166 		p2v = null;
167 		p3avs.clear();
168 		p3bvs.clear();
169 	}
170 
171 	/***
172 	 * This returns all the (warning) messages collected during verification.
173 	 * A prefix shows from which verifying pass a message originates.
174 	 */
175 	public String[] getMessages(){
176 		ArrayList messages = new ArrayList();
177 
178 		if (p1v != null){
179 			String[] p1m = p1v.getMessages();
180 			for (int i=0; i<p1m.length; i++){
181 				messages.add("Pass 1: "+p1m[i]);
182 			}
183 		}
184 		if (p2v != null){
185 			String[] p2m = p2v.getMessages();
186 			for (int i=0; i<p2m.length; i++){
187 				messages.add("Pass 2: "+p2m[i]);
188 			}
189 		}
190 		Iterator p3as = p3avs.values().iterator();
191 		while (p3as.hasNext()){
192 			Pass3aVerifier pv = (Pass3aVerifier) p3as.next();
193 			String[] p3am = pv.getMessages();
194 			int meth = pv.getMethodNo();
195 			for (int i=0; i<p3am.length; i++){
196 				messages.add("Pass 3a, method "+meth+
197 					     " ('"+
198 					     org.apache.bcel.Repository
199 					     .lookupClass(classname)
200 					     .getMethods()[meth] +
201 					     "'): "+p3am[i]);
202 			}
203 		}
204 		Iterator p3bs = p3bvs.values().iterator();
205 		while (p3bs.hasNext()){
206 			Pass3bVerifier pv = (Pass3bVerifier) p3bs.next();
207 			String[] p3bm = pv.getMessages();
208 			int meth = pv.getMethodNo();
209 			for (int i=0; i<p3bm.length; i++){
210 				messages.add("Pass 3b, method "+meth+
211 					     " ('"+
212 					     org.apache.bcel.Repository.
213 					     lookupClass(classname).
214 					     getMethods()[meth] +
215 					     "'): "+p3bm[i]);
216 			}
217 		}
218 
219 		String[] ret = new String[messages.size()];
220 		for (int i=0; i< messages.size(); i++){
221 			ret[i] = (String) messages.get(i);
222 		}
223 
224 		return ret;
225 	}
226 
227 	/***
228 	 * Verifies class files.
229 	 * This is a simple demonstration of how the API of BCEL's
230 	 * class file verifier "JustIce" may be used.
231 	 * You should supply command-line arguments which are
232 	 * fully qualified namea of the classes to verify. These class files
233 	 * must be somewhere in your CLASSPATH (refer to Sun's
234 	 * documentation for questions about this) or you must have put the classes
235 	 * into the BCEL Repository yourself (via 'addClass(JavaClass)').
236 	 */
237 	public static void main(String [] args){
238 		System.out.println("JustIce by Enver Haase, (C) 2001-2002.\n<http://bcel.sourceforge.net>\n<http://jakarta.apache.org/bcel>\n");
239 	  for(int k=0; k < args.length; k++) {
240 
241 			if (args[k].endsWith(".class")){
242 				int dotclasspos = args[k].lastIndexOf(".class");
243 				if (dotclasspos != -1) args[k] = args[k].substring(0,dotclasspos);
244 			}
245 
246 			args[k] = args[k].replace('/', '.');
247 
248 			System.out.println("Now verifying: "+args[k]+"\n");
249 
250 			Verifier v = VerifierFactory.getVerifier(args[k]);
251 			VerificationResult vr;
252 
253 			vr = v.doPass1();
254 			System.out.println("Pass 1:\n"+vr);
255 
256 			vr = v.doPass2();
257 			System.out.println("Pass 2:\n"+vr);
258 
259 			if (vr == VerificationResult.VR_OK){
260 				JavaClass jc = org.apache.bcel.Repository
261 				    .lookupClass(args[k]);
262 				for (int i=0; i<jc.getMethods().length; i++){
263 					vr = v.doPass3a(i);
264 					System.out.println("Pass 3a, method number "+i+" ['"+jc.getMethods()[i]+"']:\n"+vr);
265 
266 					vr = v.doPass3b(i);
267 					System.out.println("Pass 3b, method number "+i+" ['"+jc.getMethods()[i]+"']:\n"+vr);
268 				}
269 			}
270 
271 			System.out.println("Warnings:");
272 			String[] warnings = v.getMessages();
273 			if (warnings.length == 0) System.out.println("<none>");
274 			for (int j=0; j<warnings.length; j++){
275 				System.out.println(warnings[j]);
276 			}
277 
278 			System.out.println("\n");
279 
280 			// avoid swapping.
281 	  	v.flush();
282 	  	org.apache.bcel.Repository.clearCache();
283 		System.gc();
284 	  }
285 	}
286 }
This page was automatically generated by Maven