You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ch...@apache.org on 2015/07/18 06:56:40 UTC

svn commit: r1691680 - in /commons/proper/bcel/trunk: ./ src/changes/ src/main/java/org/apache/bcel/verifier/statics/ src/test/java/org/apache/bcel/verifier/ src/test/java/org/apache/bcel/verifier/tests/

Author: chas
Date: Sat Jul 18 04:56:40 2015
New Revision: 1691680

URL: http://svn.apache.org/r1691680
Log:
BCEL-187
Verification error when an invoke references a method defined in superclass

Added:
    commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/VerifierInvokeTestCase.java
    commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/tests/TestLegalInvokeInterface01.java   (with props)
    commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/tests/TestLegalInvokeSpecial01.java   (with props)
    commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/tests/TestLegalInvokeSpecial02.java   (with props)
    commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/tests/TestLegalInvokeStatic01.java   (with props)
    commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/tests/TestLegalInvokeVirtual01.java   (with props)
    commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/tests/TestLegalInvokeVirtual02.java   (with props)
Modified:
    commons/proper/bcel/trunk/pom.xml
    commons/proper/bcel/trunk/src/changes/changes.xml
    commons/proper/bcel/trunk/src/main/java/org/apache/bcel/verifier/statics/Pass3aVerifier.java
    commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/AbstractVerifierTestCase.java

Modified: commons/proper/bcel/trunk/pom.xml
URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/pom.xml?rev=1691680&r1=1691679&r2=1691680&view=diff
==============================================================================
--- commons/proper/bcel/trunk/pom.xml (original)
+++ commons/proper/bcel/trunk/pom.xml Sat Jul 18 04:56:40 2015
@@ -41,8 +41,8 @@
   <properties>
     <project.build.sourceEncoding>ISO-8859-1</project.build.sourceEncoding>
     <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
-    <maven.compiler.source>1.7</maven.compiler.source>
-    <maven.compiler.target>1.7</maven.compiler.target>
+    <maven.compiler.source>1.5</maven.compiler.source>
+    <maven.compiler.target>1.5</maven.compiler.target>
     <commons.componentid>bcel</commons.componentid>
     <commons.release.version>6.0</commons.release.version>
     <commons.release.desc>(Java 5.0+)</commons.release.desc>

Modified: commons/proper/bcel/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/changes/changes.xml?rev=1691680&r1=1691679&r2=1691680&view=diff
==============================================================================
--- commons/proper/bcel/trunk/src/changes/changes.xml (original)
+++ commons/proper/bcel/trunk/src/changes/changes.xml Sat Jul 18 04:56:40 2015
@@ -63,6 +63,9 @@ The <action> type attribute can be add,u
 
   <body>
     <release version="6.0" date="TBA" description="Major release with Java 7 and 8 support">
+      <action issue="BCEL-187" type="fix" due-to="Jérôme Leroux">
+        Verification error when an invoke references a method defined in superclass
+      </action>
       <action issue="BCEL-218" type="fix" due-to="chas">
         Remove ObjectType cache.
       </action>

Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/verifier/statics/Pass3aVerifier.java
URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/verifier/statics/Pass3aVerifier.java?rev=1691680&r1=1691679&r2=1691680&view=diff
==============================================================================
--- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/verifier/statics/Pass3aVerifier.java (original)
+++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/verifier/statics/Pass3aVerifier.java Sat Jul 18 04:56:40 2015
@@ -1079,18 +1079,9 @@ public final class Pass3aVerifier extend
             // too. So are the allowed method names.
             String classname = o.getClassName(cpg);
             JavaClass jc = Repository.lookupClass(classname);
-            Method[] ms = jc.getMethods();
-            Method m = null;
-            for (Method element : ms) {
-                if ( (element.getName().equals(o.getMethodName(cpg))) &&
-                     (Type.getReturnType(element.getSignature()).equals(o.getReturnType(cpg))) &&
-                     (objarrayequals(Type.getArgumentTypes(element.getSignature()), o.getArgumentTypes(cpg))) ){
-                    m = element;
-                    break;
-                }
-            }
+            Method m = getMethodRecursive(jc, o);
             if (m == null){
-                constraintViolated(o, "Referenced method '"+o.getMethodName(cpg)+"' with expected signature '"+o.getSignature(cpg)+"' not found in class '"+jc.getClassName()+"'. The native verifier does allow the method to be declared in some superinterface, which the Java Virtual Machine Specification, Second Edition does not.");
+                constraintViolated(o, "Referenced method '"+o.getMethodName(cpg)+"' with expected signature '"+o.getSignature(cpg)+"' not found in class '"+jc.getClassName()+"'.");
             }
             if (jc.isClass()){
                 constraintViolated(o, "Referenced class '"+jc.getClassName()+"' is a class, but not an interface as expected.");
@@ -1101,6 +1092,59 @@ public final class Pass3aVerifier extend
             }
         }
 
+        /**
+         * Looks for the method referenced by the given invoke instruction in the given class or its super classes and super interfaces.
+         * @param jc the class that defines the referenced method
+         * @param invoke the instruction that references the method
+         * @return the referenced method or null if not found.
+         */
+        private Method getMethodRecursive(JavaClass jc, InvokeInstruction invoke) throws ClassNotFoundException{
+            Method m;
+            //look in the given class
+            m = getMethod(jc, invoke);
+            if(m != null){
+                //method found in given class
+                return m;
+            }
+            //method not found, look in super classes
+            for(JavaClass superclass : jc.getSuperClasses()){
+                m = getMethod(superclass, invoke);
+                if(m != null){
+                    //method found in super class
+                    return m;
+                }
+            }
+            //method not found, look in super interfaces
+            for(JavaClass superclass : jc.getInterfaces()){
+                m = getMethod(superclass, invoke);
+                if(m != null){
+                    //method found in super interface
+                    return m;
+                }
+            }
+            //method not found in the hierarchy
+            return null;
+        }
+        /**
+         * Looks for the method referenced by the given invoke instruction in the given class.
+         * @param jc the class that defines the referenced method
+         * @param invoke the instruction that references the method
+         * @return the referenced method or null if not found.
+         */
+        private Method getMethod(JavaClass jc, InvokeInstruction invoke){
+            Method[] ms = jc.getMethods();
+            Method m = null;
+            for (Method element : ms) {
+                if ( (element.getName().equals(invoke.getMethodName(cpg))) &&
+                     (Type.getReturnType(element.getSignature()).equals(invoke.getReturnType(cpg))) &&
+                     (objarrayequals(Type.getArgumentTypes(element.getSignature()), invoke.getArgumentTypes(cpg))) ){
+                    return element;
+                }
+            }
+            
+            return null;
+        }
+
         /** Checks if the constraints of operands of the said instruction(s) are satisfied. */
         @Override
         public void visitINVOKESPECIAL(INVOKESPECIAL o){
@@ -1111,18 +1155,9 @@ public final class Pass3aVerifier extend
             // too. So are the allowed method names.
             String classname = o.getClassName(cpg);
             JavaClass jc = Repository.lookupClass(classname);
-            Method[] ms = jc.getMethods();
-            Method m = null;
-            for (Method element : ms) {
-                if ( (element.getName().equals(o.getMethodName(cpg))) &&
-                     (Type.getReturnType(element.getSignature()).equals(o.getReturnType(cpg))) &&
-                     (objarrayequals(Type.getArgumentTypes(element.getSignature()), o.getArgumentTypes(cpg))) ){
-                    m = element;
-                    break;
-                }
-            }
+            Method m = getMethodRecursive(jc, o);
             if (m == null){
-                constraintViolated(o, "Referenced method '"+o.getMethodName(cpg)+"' with expected signature '"+o.getSignature(cpg)+"' not found in class '"+jc.getClassName()+"'. The native verifier does allow the method to be declared in some superclass or implemented interface, which the Java Virtual Machine Specification, Second Edition does not.");
+                constraintViolated(o, "Referenced method '"+o.getMethodName(cpg)+"' with expected signature '"+o.getSignature(cpg)+"' not found in class '"+jc.getClassName()+"'.");
             }
 
             JavaClass current = Repository.lookupClass(myOwner.getClassName());
@@ -1177,18 +1212,9 @@ public final class Pass3aVerifier extend
             // too. So are the allowed method names.
             String classname = o.getClassName(cpg);
             JavaClass jc = Repository.lookupClass(classname);
-            Method[] ms = jc.getMethods();
-            Method m = null;
-            for (Method element : ms) {
-                if ( (element.getName().equals(o.getMethodName(cpg))) &&
-                     (Type.getReturnType(element.getSignature()).equals(o.getReturnType(cpg))) &&
-                     (objarrayequals(Type.getArgumentTypes(element.getSignature()), o.getArgumentTypes(cpg))) ){
-                    m = element;
-                    break;
-                }
-            }
+            Method m = getMethodRecursive(jc, o);
             if (m == null){
-                constraintViolated(o, "Referenced method '"+o.getMethodName(cpg)+"' with expected signature '"+o.getSignature(cpg) +"' not found in class '"+jc.getClassName()+"'. The native verifier possibly allows the method to be declared in some superclass or implemented interface, which the Java Virtual Machine Specification, Second Edition does not.");
+                constraintViolated(o, "Referenced method '"+o.getMethodName(cpg)+"' with expected signature '"+o.getSignature(cpg) +"' not found in class '"+jc.getClassName()+"'.");
             } else if (! (m.isStatic())){ // implies it's not abstract, verified in pass 2.
                 constraintViolated(o, "Referenced method '"+o.getMethodName(cpg)+"' has ACC_STATIC unset.");
             }
@@ -1210,18 +1236,9 @@ public final class Pass3aVerifier extend
             // too. So are the allowed method names.
             String classname = o.getClassName(cpg);
             JavaClass jc = Repository.lookupClass(classname);
-            Method[] ms = jc.getMethods();
-            Method m = null;
-            for (Method element : ms) {
-                if ( (element.getName().equals(o.getMethodName(cpg))) &&
-                     (Type.getReturnType(element.getSignature()).equals(o.getReturnType(cpg))) &&
-                     (objarrayequals(Type.getArgumentTypes(element.getSignature()), o.getArgumentTypes(cpg))) ){
-                    m = element;
-                    break;
-                }
-            }
+            Method m = getMethodRecursive(jc, o);
             if (m == null){
-                constraintViolated(o, "Referenced method '"+o.getMethodName(cpg)+"' with expected signature '"+o.getSignature(cpg)+"' not found in class '"+jc.getClassName()+"'. The native verifier does allow the method to be declared in some superclass or implemented interface, which the Java Virtual Machine Specification, Second Edition does not.");
+                constraintViolated(o, "Referenced method '"+o.getMethodName(cpg)+"' with expected signature '"+o.getSignature(cpg)+"' not found in class '"+jc.getClassName()+"'.");
             }
             if (! (jc.isClass())){
                 constraintViolated(o, "Referenced class '"+jc.getClassName()+"' is an interface, but not a class as expected.");

Modified: commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/AbstractVerifierTestCase.java
URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/AbstractVerifierTestCase.java?rev=1691680&r1=1691679&r2=1691680&view=diff
==============================================================================
--- commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/AbstractVerifierTestCase.java (original)
+++ commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/AbstractVerifierTestCase.java Sat Jul 18 04:56:40 2015
@@ -18,11 +18,11 @@
 
 package org.apache.bcel.verifier;
 
-import junit.framework.TestCase;
-
 import org.apache.bcel.Repository;
 import org.apache.bcel.classfile.JavaClass;
 
+import junit.framework.TestCase;
+
 public abstract class AbstractVerifierTestCase extends TestCase {
 
     public static final String TEST_PACKAGE = "org.apache.bcel.verifier.tests.";

Added: commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/VerifierInvokeTestCase.java
URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/VerifierInvokeTestCase.java?rev=1691680&view=auto
==============================================================================
--- commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/VerifierInvokeTestCase.java (added)
+++ commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/VerifierInvokeTestCase.java Sat Jul 18 04:56:40 2015
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ */
+
+package org.apache.bcel.verifier;
+
+
+public class VerifierInvokeTestCase extends AbstractVerifierTestCase {
+
+    public void testLegalInvokeVirtual() {
+        assertVerifyOK("TestLegalInvokeVirtual01", "Verification of invokevirtual on method defined in superclass must pass.");
+        assertVerifyOK("TestLegalInvokeVirtual02", "Verification of invokevirtual on method defined in superinterface must pass.");
+    }
+    
+    public void testLegalInvokeStatic() {
+        assertVerifyOK("TestLegalInvokeStatic01", "Verification of invokestatic on method defined in superclass must pass.");
+    }
+    
+    public void testLegalInvokeInterface() {
+        assertVerifyOK("TestLegalInvokeInterface01", "Verification of invokeinterface on method defined in superinterface must pass.");
+    }
+    
+    public void testLegalInvokeSpecial() {
+        assertVerifyOK("TestLegalInvokeSpecial01", "Verification of invokespecial on method defined in superclass must pass.");
+        assertVerifyOK("TestLegalInvokeSpecial02", "Verification of invokespecial on method defined in superclass must pass.");
+    }
+}

Added: commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/tests/TestLegalInvokeInterface01.java
URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/tests/TestLegalInvokeInterface01.java?rev=1691680&view=auto
==============================================================================
--- commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/tests/TestLegalInvokeInterface01.java (added)
+++ commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/tests/TestLegalInvokeInterface01.java Sat Jul 18 04:56:40 2015
@@ -0,0 +1,12 @@
+package org.apache.bcel.verifier.tests;
+
+public class TestLegalInvokeInterface01{
+
+    public static void test1(Interface01 t){
+        t.run();
+    }
+}
+
+interface Interface01 extends Runnable {
+    
+}
\ No newline at end of file

Propchange: commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/tests/TestLegalInvokeInterface01.java
------------------------------------------------------------------------------
    svn:executable = *

Added: commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/tests/TestLegalInvokeSpecial01.java
URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/tests/TestLegalInvokeSpecial01.java?rev=1691680&view=auto
==============================================================================
--- commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/tests/TestLegalInvokeSpecial01.java (added)
+++ commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/tests/TestLegalInvokeSpecial01.java Sat Jul 18 04:56:40 2015
@@ -0,0 +1,9 @@
+package org.apache.bcel.verifier.tests;
+
+public class TestLegalInvokeSpecial01{
+
+    public static void test1(){
+       new TestLegalInvokeSpecial01().getClass();
+    }
+    
+}

Propchange: commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/tests/TestLegalInvokeSpecial01.java
------------------------------------------------------------------------------
    svn:executable = *

Added: commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/tests/TestLegalInvokeSpecial02.java
URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/tests/TestLegalInvokeSpecial02.java?rev=1691680&view=auto
==============================================================================
--- commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/tests/TestLegalInvokeSpecial02.java (added)
+++ commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/tests/TestLegalInvokeSpecial02.java Sat Jul 18 04:56:40 2015
@@ -0,0 +1,11 @@
+package org.apache.bcel.verifier.tests;
+
+abstract public class TestLegalInvokeSpecial02 implements Runnable{
+
+    public static void test1(TestLegalInvokeSpecial02 t, int i){
+        if(i > 0){
+            t.run();
+        }
+    }
+    
+}

Propchange: commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/tests/TestLegalInvokeSpecial02.java
------------------------------------------------------------------------------
    svn:executable = *

Added: commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/tests/TestLegalInvokeStatic01.java
URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/tests/TestLegalInvokeStatic01.java?rev=1691680&view=auto
==============================================================================
--- commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/tests/TestLegalInvokeStatic01.java (added)
+++ commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/tests/TestLegalInvokeStatic01.java Sat Jul 18 04:56:40 2015
@@ -0,0 +1,9 @@
+package org.apache.bcel.verifier.tests;
+
+public class TestLegalInvokeStatic01 extends Thread{
+
+    public static void test1() throws InterruptedException{
+       Thread.sleep(0);
+    }
+    
+}

Propchange: commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/tests/TestLegalInvokeStatic01.java
------------------------------------------------------------------------------
    svn:executable = *

Added: commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/tests/TestLegalInvokeVirtual01.java
URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/tests/TestLegalInvokeVirtual01.java?rev=1691680&view=auto
==============================================================================
--- commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/tests/TestLegalInvokeVirtual01.java (added)
+++ commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/tests/TestLegalInvokeVirtual01.java Sat Jul 18 04:56:40 2015
@@ -0,0 +1,9 @@
+package org.apache.bcel.verifier.tests;
+
+public class TestLegalInvokeVirtual01 {
+
+    public static void test1(){
+        new TestLegalInvokeVirtual01().toString();
+    }
+    
+}

Propchange: commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/tests/TestLegalInvokeVirtual01.java
------------------------------------------------------------------------------
    svn:executable = *

Added: commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/tests/TestLegalInvokeVirtual02.java
URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/tests/TestLegalInvokeVirtual02.java?rev=1691680&view=auto
==============================================================================
--- commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/tests/TestLegalInvokeVirtual02.java (added)
+++ commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/tests/TestLegalInvokeVirtual02.java Sat Jul 18 04:56:40 2015
@@ -0,0 +1,11 @@
+package org.apache.bcel.verifier.tests;
+
+abstract public class TestLegalInvokeVirtual02 implements Runnable{
+
+    public static void test1(TestLegalInvokeVirtual02 t, int i){
+        if(i > 0){
+            t.run();
+        }
+    }
+    
+}

Propchange: commons/proper/bcel/trunk/src/test/java/org/apache/bcel/verifier/tests/TestLegalInvokeVirtual02.java
------------------------------------------------------------------------------
    svn:executable = *