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