You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Verifier.java 9.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. package org.aspectj.apache.bcel.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 (https://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. * <https://www.apache.org/>.
  54. */
  55. import java.util.ArrayList;
  56. import java.util.HashMap;
  57. import java.util.Iterator;
  58. import org.aspectj.apache.bcel.classfile.JavaClass;
  59. import org.aspectj.apache.bcel.verifier.statics.Pass1Verifier;
  60. import org.aspectj.apache.bcel.verifier.statics.Pass2Verifier;
  61. import org.aspectj.apache.bcel.verifier.statics.Pass3aVerifier;
  62. import org.aspectj.apache.bcel.verifier.structurals.Pass3bVerifier;
  63. /**
  64. * A Verifier instance is there to verify a class file according to The Java Virtual
  65. * Machine Specification, 2nd Edition.
  66. *
  67. * Pass-3b-verification includes pass-3a-verification;
  68. * pass-3a-verification includes pass-2-verification;
  69. * pass-2-verification includes pass-1-verification.
  70. *
  71. * A Verifier creates PassVerifier instances to perform the actual verification.
  72. * Verifier instances are usually generated by the VerifierFactory.
  73. *
  74. * @version $Id: Verifier.java,v 1.3 2009/09/09 19:56:20 aclement Exp $
  75. * @author <A HREF="https://www.inf.fu-berlin.de/~ehaase"/>Enver Haase</A>
  76. * @see org.aspectj.apache.bcel.verifier.VerifierFactory
  77. * @see org.aspectj.apache.bcel.verifier.PassVerifier
  78. */
  79. public class Verifier{
  80. /**
  81. * The name of the class this verifier operates on.
  82. */
  83. private final String classname;
  84. /** A Pass1Verifier for this Verifier instance. */
  85. private Pass1Verifier p1v;
  86. /** A Pass2Verifier for this Verifier instance. */
  87. private Pass2Verifier p2v;
  88. /** The Pass3aVerifiers for this Verifier instance. Key: Interned string specifying the method number. */
  89. private HashMap<String, Pass3aVerifier> p3avs = new HashMap<String, Pass3aVerifier>();
  90. /** The Pass3bVerifiers for this Verifier instance. Key: Interned string specifying the method number. */
  91. private HashMap<String, Pass3bVerifier> p3bvs = new HashMap<String, Pass3bVerifier>();
  92. /** Returns the VerificationResult for the given pass. */
  93. public VerificationResult doPass1(){
  94. if (p1v == null){
  95. p1v = new Pass1Verifier(this);
  96. }
  97. return p1v.verify();
  98. }
  99. /** Returns the VerificationResult for the given pass. */
  100. public VerificationResult doPass2(){
  101. if (p2v == null){
  102. p2v = new Pass2Verifier(this);
  103. }
  104. return p2v.verify();
  105. }
  106. /** Returns the VerificationResult for the given pass. */
  107. public VerificationResult doPass3a(int method_no){
  108. String key = Integer.toString(method_no);
  109. Pass3aVerifier p3av;
  110. p3av = (p3avs.get(key));
  111. if (p3avs.get(key) == null){
  112. p3av = new Pass3aVerifier(this, method_no);
  113. p3avs.put(key, p3av);
  114. }
  115. return p3av.verify();
  116. }
  117. /** Returns the VerificationResult for the given pass. */
  118. public VerificationResult doPass3b(int method_no){
  119. String key = Integer.toString(method_no);
  120. Pass3bVerifier p3bv;
  121. p3bv = (p3bvs.get(key));
  122. if (p3bvs.get(key) == null){
  123. p3bv = new Pass3bVerifier(this, method_no);
  124. p3bvs.put(key, p3bv);
  125. }
  126. return p3bv.verify();
  127. }
  128. /**
  129. * Instantiation is done by the VerifierFactory.
  130. *
  131. * @see VerifierFactory
  132. */
  133. Verifier(String fully_qualified_classname){
  134. classname = fully_qualified_classname;
  135. flush();
  136. }
  137. /**
  138. * Returns the name of the class this verifier operates on.
  139. * This is particularly interesting when this verifier was created
  140. * recursively by another Verifier and you got a reference to this
  141. * Verifier by the getVerifiers() method of the VerifierFactory.
  142. * @see VerifierFactory
  143. */
  144. public final String getClassName(){
  145. return classname;
  146. }
  147. /**
  148. * Forget everything known about the class file; that means, really
  149. * start a new verification of a possibly different class file from
  150. * BCEL's repository.
  151. *
  152. */
  153. public void flush(){
  154. p1v = null;
  155. p2v = null;
  156. p3avs.clear();
  157. p3bvs.clear();
  158. }
  159. /**
  160. * This returns all the (warning) messages collected during verification.
  161. * A prefix shows from which verifying pass a message originates.
  162. */
  163. public String[] getMessages(){
  164. ArrayList messages = new ArrayList();
  165. if (p1v != null){
  166. String[] p1m = p1v.getMessages();
  167. for (int i=0; i<p1m.length; i++){
  168. messages.add("Pass 1: "+p1m[i]);
  169. }
  170. }
  171. if (p2v != null){
  172. String[] p2m = p2v.getMessages();
  173. for (int i=0; i<p2m.length; i++){
  174. messages.add("Pass 2: "+p2m[i]);
  175. }
  176. }
  177. Iterator<Pass3aVerifier> p3as = p3avs.values().iterator();
  178. while (p3as.hasNext()){
  179. Pass3aVerifier pv = p3as.next();
  180. String[] p3am = pv.getMessages();
  181. int meth = pv.getMethodNo();
  182. for (int i=0; i<p3am.length; i++){
  183. messages.add("Pass 3a, method "+meth+
  184. " ('"+
  185. org.aspectj.apache.bcel.Repository
  186. .lookupClass(classname)
  187. .getMethods()[meth] +
  188. "'): "+p3am[i]);
  189. }
  190. }
  191. Iterator<Pass3bVerifier> p3bs = p3bvs.values().iterator();
  192. while (p3bs.hasNext()){
  193. Pass3bVerifier pv = p3bs.next();
  194. String[] p3bm = pv.getMessages();
  195. int meth = pv.getMethodNo();
  196. for (int i=0; i<p3bm.length; i++){
  197. messages.add("Pass 3b, method "+meth+
  198. " ('"+
  199. org.aspectj.apache.bcel.Repository.
  200. lookupClass(classname).
  201. getMethods()[meth] +
  202. "'): "+p3bm[i]);
  203. }
  204. }
  205. String[] ret = new String[messages.size()];
  206. for (int i=0; i< messages.size(); i++){
  207. ret[i] = (String) messages.get(i);
  208. }
  209. return ret;
  210. }
  211. /**
  212. * Verifies class files.
  213. * This is a simple demonstration of how the API of BCEL's
  214. * class file verifier "JustIce" may be used.
  215. * You should supply command-line arguments which are
  216. * fully qualified namea of the classes to verify. These class files
  217. * must be somewhere in your CLASSPATH (refer to Sun's
  218. * documentation for questions about this) or you must have put the classes
  219. * into the BCEL Repository yourself (via 'addClass(JavaClass)').
  220. */
  221. public static void main(String [] args){
  222. System.out.println("JustIce by Enver Haase, (C) 2001-2002.\n<https://bcel.sourceforge.net>\n<https://jakarta.apache.org/bcel>\n");
  223. for(int k=0; k < args.length; k++) {
  224. if (args[k].endsWith(".class")){
  225. int dotclasspos = args[k].lastIndexOf(".class");
  226. if (dotclasspos != -1) args[k] = args[k].substring(0,dotclasspos);
  227. }
  228. args[k] = args[k].replace('/', '.');
  229. System.out.println("Now verifying: "+args[k]+"\n");
  230. Verifier v = VerifierFactory.getVerifier(args[k]);
  231. VerificationResult vr;
  232. vr = v.doPass1();
  233. System.out.println("Pass 1:\n"+vr);
  234. vr = v.doPass2();
  235. System.out.println("Pass 2:\n"+vr);
  236. if (vr == VerificationResult.VR_OK){
  237. JavaClass jc = org.aspectj.apache.bcel.Repository
  238. .lookupClass(args[k]);
  239. for (int i=0; i<jc.getMethods().length; i++){
  240. vr = v.doPass3a(i);
  241. System.out.println("Pass 3a, method number "+i+" ['"+jc.getMethods()[i]+"']:\n"+vr);
  242. vr = v.doPass3b(i);
  243. System.out.println("Pass 3b, method number "+i+" ['"+jc.getMethods()[i]+"']:\n"+vr);
  244. }
  245. }
  246. System.out.println("Warnings:");
  247. String[] warnings = v.getMessages();
  248. if (warnings.length == 0) System.out.println("<none>");
  249. for (int j=0; j<warnings.length; j++){
  250. System.out.println(warnings[j]);
  251. }
  252. System.out.println("\n");
  253. // avoid swapping.
  254. v.flush();
  255. org.aspectj.apache.bcel.Repository.clearCache();
  256. System.gc();
  257. }
  258. }
  259. }