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