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"));
+ }
}