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 2023/09/15 21:34:44 UTC

[commons-bcel] branch master updated: Fix for type.getType(...) use on non-signature type names (#221)

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 87a5cae7 Fix for type.getType(...) use on non-signature type names (#221)
87a5cae7 is described below

commit 87a5cae734c7aaab25b731604d41bb2f77610c50
Author: nbauma109 <nb...@users.noreply.github.com>
AuthorDate: Fri Sep 15 23:34:39 2023 +0200

    Fix for type.getType(...) use on non-signature type names (#221)
    
    * Fix a regression of PR#171 - Correct usage of Type.getType(...)
    
    * Remove fall through
    
    * added tests - do not throw
    
    * fix coverage
    
    * fix: use StringUtils.isEmpty(internalTypeName)
    
    * Fix name of method to camel case: internalTypeNameToSignature
    
    * Make Const.SHORT_TYPE_NAMES public for Type.internalTypeNameToSignature
    
    * Checkstyle WhitespaceAround
    
    ---------
    
    Co-authored-by: nbauma109 <nb...@github.com>
    Co-authored-by: Gary Gregory <ga...@users.noreply.github.com>
---
 src/main/java/org/apache/bcel/Const.java           |  2 +-
 src/main/java/org/apache/bcel/generic/LDC.java     |  2 +-
 src/main/java/org/apache/bcel/generic/Type.java    | 21 ++++++-
 .../java/org/apache/bcel/generic/TypeTestCase.java | 70 +++++++++++++++++++++-
 4 files changed, 90 insertions(+), 5 deletions(-)

diff --git a/src/main/java/org/apache/bcel/Const.java b/src/main/java/org/apache/bcel/Const.java
index 177fef5b..a76f7326 100644
--- a/src/main/java/org/apache/bcel/Const.java
+++ b/src/main/java/org/apache/bcel/Const.java
@@ -2848,7 +2848,7 @@ public final class Const {
     /**
      * The signature characters corresponding to primitive types, e.g., SHORT_TYPE_NAMES[T_INT] = "I"
      */
-    private static final String[] SHORT_TYPE_NAMES = {ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, "Z", "C", "F", "D", "B", "S", "I", "J", "V",
+    public static final String[] SHORT_TYPE_NAMES = {ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, "Z", "C", "F", "D", "B", "S", "I", "J", "V",
         ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE};
 
     /**
diff --git a/src/main/java/org/apache/bcel/generic/LDC.java b/src/main/java/org/apache/bcel/generic/LDC.java
index 85f1c7c2..eba856e9 100644
--- a/src/main/java/org/apache/bcel/generic/LDC.java
+++ b/src/main/java/org/apache/bcel/generic/LDC.java
@@ -108,7 +108,7 @@ public class LDC extends CPInstruction implements PushInstruction, ExceptionThro
         case org.apache.bcel.Const.CONSTANT_Class:
             final int nameIndex = ((org.apache.bcel.classfile.ConstantClass) c).getNameIndex();
             c = cpg.getConstantPool().getConstant(nameIndex);
-            return Type.getType(((org.apache.bcel.classfile.ConstantUtf8) c).getBytes());
+            return Type.getType(Type.internalTypeNameToSignature(((org.apache.bcel.classfile.ConstantUtf8) c).getBytes()));
         default: // Never reached
             throw new IllegalArgumentException("Unknown or invalid constant type at " + super.getIndex());
         }
diff --git a/src/main/java/org/apache/bcel/generic/Type.java b/src/main/java/org/apache/bcel/generic/Type.java
index edd62bc5..f5e9c5ea 100644
--- a/src/main/java/org/apache/bcel/generic/Type.java
+++ b/src/main/java/org/apache/bcel/generic/Type.java
@@ -25,6 +25,7 @@ import org.apache.bcel.Const;
 import org.apache.bcel.classfile.ClassFormatException;
 import org.apache.bcel.classfile.InvalidMethodSignatureException;
 import org.apache.bcel.classfile.Utility;
+import org.apache.commons.lang3.StringUtils;
 
 /**
  * Abstract super class for all possible java types, namely basic types such as int, object types like String and array
@@ -180,7 +181,7 @@ public abstract class Type {
     public static Type getType(final Class<?> cls) {
         Objects.requireNonNull(cls, "cls");
         /*
-         * That's an amzingly easy case, because getName() returns the signature. That's what we would have liked anyway.
+         * That's an amazingly easy case, because getName() returns the signature. That's what we would have liked anyway.
          */
         if (cls.isArray()) {
             return getType(cls.getName());
@@ -365,6 +366,24 @@ public abstract class Type {
         return type ^ signature.hashCode();
     }
 
+    static String internalTypeNameToSignature(final String internalTypeName) {
+        if (StringUtils.isEmpty(internalTypeName) || StringUtils.equalsAny(internalTypeName, Const.SHORT_TYPE_NAMES)) {
+            return internalTypeName;
+        }
+        switch (internalTypeName.charAt(0)) {
+            case '[':
+                return internalTypeName;
+            case 'L':
+            case 'T':
+                if (internalTypeName.charAt(internalTypeName.length() - 1) == ';') {
+                    return internalTypeName;
+                }
+                return 'L' + internalTypeName + ';';
+            default:
+                return 'L' + internalTypeName + ';';
+        }
+    }
+
     /**
      * boolean, short and char variable are considered as int in the stack or local variable area. Returns {@link Type#INT}
      * for {@link Type#BOOLEAN}, {@link Type#SHORT} or {@link Type#CHAR}, otherwise returns the given type.
diff --git a/src/test/java/org/apache/bcel/generic/TypeTestCase.java b/src/test/java/org/apache/bcel/generic/TypeTestCase.java
index a2632151..242e1004 100644
--- a/src/test/java/org/apache/bcel/generic/TypeTestCase.java
+++ b/src/test/java/org/apache/bcel/generic/TypeTestCase.java
@@ -16,9 +16,16 @@
  */
 package org.apache.bcel.generic;
 
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
+import org.apache.bcel.Repository;
+import org.apache.bcel.classfile.Code;
+import org.apache.bcel.classfile.JavaClass;
+import org.apache.bcel.classfile.Method;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 
 public class TypeTestCase {
     @Test
@@ -32,4 +39,63 @@ public class TypeTestCase {
         assertEquals(expectedValue, actualValue, "Type.getType");
     }
 
+    @ParameterizedTest
+    @ValueSource(strings = {
+    // @formatter:off
+        "java/io/Externalizable",
+        "java/io/ObjectOutputStream",
+        "java/io/Serializable",
+        "java/lang/Cloneable",
+        "java/lang/RuntimeException",
+        "java/lang/String",
+        "java/lang/System",
+        "java/lang/Throwable",
+        "java/net/URI",
+        "java/sql/Statement",
+        "java/util/ArrayList",
+        "java/util/Calendar",
+        "java/util/EnumMap",
+        "java/util/HashSet",
+        "java/util/Iterator",
+        "java/util/LinkedList",
+        "java/util/List",
+        "java/util/Map",
+        "java/util/concurrent/ConcurrentMap",
+        "java/util/concurrent/ExecutorService",
+        "org/apache/bcel/classfile/JavaClass",
+        "org/apache/bcel/classfile/Method",
+        "org/apache/bcel/classfile/Synthetic",
+        "org/apache/bcel/generic/ConstantPoolGen",
+        "org/apache/bcel/generic/MethodGen"})
+    // @formatter:on
+    public void testLDC(final String className) throws Exception {
+        final JavaClass jc = Repository.lookupClass(className);
+        final ConstantPoolGen cpg = new ConstantPoolGen(jc.getConstantPool());
+        for (final Method method : jc.getMethods()) {
+            final Code code = method.getCode();
+            if (code != null) {
+                final InstructionList instructionList = new InstructionList(code.getCode());
+                for (final InstructionHandle instructionHandle : instructionList) {
+                    instructionHandle.accept(new EmptyVisitor() {
+                        @Override
+                        public void visitLDC(LDC obj) {
+                            assertNotNull(obj.getValue(cpg));
+                        }
+                    });
+                }
+            }
+        }
+    }
+
+    @Test
+    public void testInternalTypeNametoSignature() {
+        assertEquals(null, Type.internalTypeNameToSignature(null));
+        assertEquals("", Type.internalTypeNameToSignature(""));
+        assertEquals("TT;", Type.internalTypeNameToSignature("TT;"));
+        assertEquals("Ljava/lang/String;", Type.internalTypeNameToSignature("Ljava/lang/String;"));
+        assertEquals("[Ljava/lang/String;", Type.internalTypeNameToSignature("[Ljava/lang/String;"));
+        assertEquals("Ljava/lang/String;", Type.internalTypeNameToSignature("java/lang/String"));
+        assertEquals("I", Type.internalTypeNameToSignature("I"));
+        assertEquals("LT;", Type.internalTypeNameToSignature("T"));
+    }
 }