You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2020/04/14 19:43:25 UTC

[commons-bcel] branch master updated: [BCEL-336] MethodGen throws NullPointerException upon Invalid Class File Missing Constructor Body.

This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-bcel.git


The following commit(s) were added to refs/heads/master by this push:
     new 1faf7d9  [BCEL-336] MethodGen throws NullPointerException upon Invalid Class File Missing Constructor Body.
1faf7d9 is described below

commit 1faf7d9f684f8d12cd87ffa641c472cc5ade610a
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Tue Apr 14 15:43:20 2020 -0400

    [BCEL-336] MethodGen throws NullPointerException upon Invalid Class File
    Missing Constructor Body.
---
 pom.xml                                            |  7 ++++
 src/changes/changes.xml                            |  1 +
 .../java/org/apache/bcel/generic/MethodGen.java    | 39 +++++++++++++---------
 .../org/apache/bcel/generic/EmptyStaticInit.java   | 27 +++++++++++++++
 .../org/apache/bcel/generic/MethodGenTestCase.java | 21 +++++++++++-
 5 files changed, 79 insertions(+), 16 deletions(-)

diff --git a/pom.xml b/pom.xml
index 5941c97..897c896 100644
--- a/pom.xml
+++ b/pom.xml
@@ -498,6 +498,13 @@
       <version>3.10</version>
       <scope>test</scope>
     </dependency>
+    <dependency>
+       <!-- BCEL-336 refers to this specific version.  -->
+      <groupId>javax</groupId>
+      <artifactId>javaee-api</artifactId>
+      <version>6.0</version>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 
   <profiles>
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 2886bf4..79eff83 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -70,6 +70,7 @@ The <action> type attribute can be add,update,fix,remove.
       <action                  type="update" dev="ggregory" due-to="Michael Ernst">Improve documentation of Pass3bVerifier (#37).</action>
       <action                  type="update" dev="ggregory" due-to="Gary Gregory">Update JUnit from 4.12 to 4.13.</action>
       <action                  type="update" dev="ggregory" due-to="Gary Gregory">Update tests from Apache Commons Lang 3.9 to 3.10.</action>
+      <action issue="BCEL-336" type="update" dev="ggregory" due-to="Tomo Suzuki, Gary Gregory">MethodGen throws NullPointerException upon Invalid Class File Missing Constructor Body.</action>
     </release> 
     <release version="6.4.1" date="2019-09-26" description="Bug fix release.">
       <action issue="BCEL-328" type="fix" dev="ggregory" due-to="Gary Gregory, Mark Roberts">java.util.EmptyStackException at org.apache.bcel.classfile.DescendingVisitor.visitModule (DescendingVisitor.java:592).</action>
diff --git a/src/main/java/org/apache/bcel/generic/MethodGen.java b/src/main/java/org/apache/bcel/generic/MethodGen.java
index fac52de..97cb547 100644
--- a/src/main/java/org/apache/bcel/generic/MethodGen.java
+++ b/src/main/java/org/apache/bcel/generic/MethodGen.java
@@ -170,18 +170,19 @@ public class MethodGen extends FieldGenOrMethodGen {
     /**
      * Instantiate from existing method.
      *
-     * @param m method
+     * @param method method
      * @param class_name class name containing this method
      * @param cp constant pool
      */
-    public MethodGen(final Method m, final String class_name, final ConstantPoolGen cp) {
-        this(m.getAccessFlags(), Type.getReturnType(m.getSignature()), Type.getArgumentTypes(m
-                .getSignature()), null /* may be overridden anyway */
-        , m.getName(), class_name,
-                ((m.getAccessFlags() & (Const.ACC_ABSTRACT | Const.ACC_NATIVE)) == 0)
-                        ? new InstructionList(m.getCode().getCode())
-                        : null, cp);
-        final Attribute[] attributes = m.getAttributes();
+    public MethodGen(final Method method, final String class_name, final ConstantPoolGen cp) {
+        this(method.getAccessFlags(), Type.getReturnType(method.getSignature()),
+            Type.getArgumentTypes(method.getSignature()), null /* may be overridden anyway */
+            , method.getName(), class_name,
+            ((method.getAccessFlags() & (Const.ACC_ABSTRACT | Const.ACC_NATIVE)) == 0)
+                ? new InstructionList(getByteCodes(method))
+                : null,
+            cp);
+        final Attribute[] attributes = method.getAttributes();
         for (final Attribute attribute : attributes) {
             Attribute a = attribute;
             if (a instanceof Code) {
@@ -194,12 +195,11 @@ public class MethodGen extends FieldGenOrMethodGen {
                         final int type = ce.getCatchType();
                         ObjectType c_type = null;
                         if (type > 0) {
-                            final String cen = m.getConstantPool().getConstantString(type,
-                                    Const.CONSTANT_Class);
-                            c_type =  ObjectType.getInstance(cen);
+                            final String cen = method.getConstantPool().getConstantString(type, Const.CONSTANT_Class);
+                            c_type = ObjectType.getInstance(cen);
                         }
                         final int end_pc = ce.getEndPC();
-                        final int length = m.getCode().getCode().length;
+                        final int length = getByteCodes(method).length;
                         InstructionHandle end;
                         if (length == end_pc) { // May happen, because end_pc is exclusive
                             end = il.getEnd();
@@ -207,8 +207,8 @@ public class MethodGen extends FieldGenOrMethodGen {
                             end = il.findHandle(end_pc);
                             end = end.getPrev(); // Make it inclusive
                         }
-                        addExceptionHandler(il.findHandle(ce.getStartPC()), end, il.findHandle(ce
-                                .getHandlerPC()), c_type);
+                        addExceptionHandler(il.findHandle(ce.getStartPC()), end, il.findHandle(ce.getHandlerPC()),
+                            c_type);
                     }
                 }
                 final Attribute[] c_attributes = c.getAttributes();
@@ -247,6 +247,15 @@ public class MethodGen extends FieldGenOrMethodGen {
         }
     }
 
+
+    private static byte[] getByteCodes(final Method method) {
+        final Code code = method.getCode();
+        if (code == null) {
+            throw new IllegalStateException(String.format("The method '%s' has no code.", method));
+        }
+        return code.getCode();
+    }
+
     /**
      * Adds a local variable to this method.
      *
diff --git a/src/test/java/org/apache/bcel/generic/EmptyStaticInit.java b/src/test/java/org/apache/bcel/generic/EmptyStaticInit.java
new file mode 100644
index 0000000..c83991b
--- /dev/null
+++ b/src/test/java/org/apache/bcel/generic/EmptyStaticInit.java
@@ -0,0 +1,27 @@
+/*
+ * 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.generic;
+
+/**
+ * 
+ */
+public class EmptyStaticInit {
+
+    static {
+        // empty
+    }
+}
diff --git a/src/test/java/org/apache/bcel/generic/MethodGenTestCase.java b/src/test/java/org/apache/bcel/generic/MethodGenTestCase.java
index 7a86df5..c116ff7 100644
--- a/src/test/java/org/apache/bcel/generic/MethodGenTestCase.java
+++ b/src/test/java/org/apache/bcel/generic/MethodGenTestCase.java
@@ -26,6 +26,8 @@ import org.apache.bcel.classfile.Method;
 import org.junit.Assert;
 import org.junit.Test;
 
+import javax.mail.internet.MailDateFormat;
+
 public class MethodGenTestCase {
 
     @interface A {
@@ -117,5 +119,22 @@ public class MethodGenTestCase {
         Assert.assertNull("scope start", lv.getStart());
         Assert.assertNull("scope end", lv.getEnd());
     }
-    
+
+    @Test(expected = IllegalStateException.class)
+    public void testInvalidNullMethodBody_MailDateFormat() throws Exception {
+        testInvalidNullMethodBody("javax.mail.internet.MailDateFormat");
+    }
+
+    @Test
+    public void testInvalidNullMethodBody_EmptyStaticInit() throws Exception {
+        testInvalidNullMethodBody("org.apache.bcel.generic.EmptyStaticInit");
+    }
+
+    private void testInvalidNullMethodBody(final String className) throws ClassNotFoundException {
+        final JavaClass jc = Repository.lookupClass(className);
+        ClassGen classGen = new ClassGen(jc);
+        for (Method method : jc.getMethods()) {
+            new MethodGen(method, jc.getClassName(), classGen.getConstantPool());
+        }
+    }
 }