PassVerifier.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  *  Unless required by applicable law or agreed to in writing, software
  12.  *  distributed under the License is distributed on an "AS IS" BASIS,
  13.  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  *  See the License for the specific language governing permissions and
  15.  *  limitations under the License.
  16.  */
  17. package org.apache.bcel.verifier;

  18. import java.util.ArrayList;
  19. import java.util.List;

  20. import org.apache.commons.lang3.ArrayUtils;

  21. /**
  22.  * A PassVerifier actually verifies a class file; it is instantiated by a Verifier. The verification should conform with
  23.  * a certain pass as described in The Java Virtual Machine Specification, 2nd edition. This book describes four passes.
  24.  * Pass one means loading the class and verifying a few static constraints. Pass two actually verifies some other
  25.  * constraints that could enforce loading in referenced class files. Pass three is the first pass that actually checks
  26.  * constraints in the code array of a method in the class file; it has two parts with the first verifying static
  27.  * constraints and the second part verifying structural constraints (where a data flow analysis is used for). The fourth
  28.  * pass, finally, performs checks that can only be done at run-time. JustIce does not have a run-time pass, but certain
  29.  * constraints that are usually delayed until run-time for performance reasons are also checked during the second part
  30.  * of pass three. PassVerifier instances perform caching. That means, if you really want a new verification run of a
  31.  * certain pass you must use a new instance of a given PassVerifier.
  32.  *
  33.  * @see Verifier
  34.  * @see #verify()
  35.  */
  36. public abstract class PassVerifier {

  37.     /** The (warning) messages. */
  38.     private final List<String> messages = new ArrayList<>();
  39.     /** The VerificationResult cache. */
  40.     private VerificationResult verificationResult;

  41.     /**
  42.      * This method adds a (warning) message to the message pool of this PassVerifier. This method is normally only
  43.      * internally used by BCEL's class file verifier "JustIce" and should not be used from the outside.
  44.      *
  45.      * @param message message to be appended to the message list.
  46.      * @see #getMessages()
  47.      */
  48.     public void addMessage(final String message) {
  49.         messages.add(message);
  50.     }

  51.     /**
  52.      * Verifies, not cached.
  53.      *
  54.      * @return The VerificationResult
  55.      */
  56.     public abstract VerificationResult do_verify();

  57.     /**
  58.      * Returns the (warning) messages that this PassVerifier accumulated during its do_verify()ing work.
  59.      *
  60.      * @return the (warning) messages.
  61.      * @see #addMessage(String)
  62.      * @see #do_verify()
  63.      */
  64.     public String[] getMessages() {
  65.         return getMessagesList().toArray(ArrayUtils.EMPTY_STRING_ARRAY);
  66.     }

  67.     /**
  68.      * Returns the (warning) messages that this PassVerifier accumulated during its do_verify()ing work.
  69.      *
  70.      * @see #addMessage(String)
  71.      * @see #do_verify()
  72.      */
  73.     public List<String> getMessagesList() {
  74.         verify(); // create messages if not already done (cached!)
  75.         return messages;
  76.     }

  77.     /**
  78.      * This method runs a verification pass conforming to the Java Virtual Machine Specification, 2nd edition, on a class
  79.      * file. PassVerifier instances perform caching; i.e. if the verify() method once determined a VerificationResult, then
  80.      * this result may be returned after every invocation of this method instead of running the verification pass anew;
  81.      * likewise with the result of getMessages().
  82.      *
  83.      * @return a VerificationResult.
  84.      * @see #getMessages()
  85.      * @see #addMessage(String)
  86.      */
  87.     public VerificationResult verify() {
  88.         if (verificationResult == null) {
  89.             verificationResult = do_verify();
  90.         }
  91.         return verificationResult;
  92.     }
  93. }