You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by br...@apache.org on 2017/09/12 16:36:55 UTC

svn commit: r1808131 - in /commons/proper/bcel/trunk/src: changes/changes.xml main/java/org/apache/bcel/classfile/Utility.java test/java/org/apache/bcel/classfile/UtilityTestCase.java

Author: britter
Date: Tue Sep 12 16:36:55 2017
New Revision: 1808131

URL: http://svn.apache.org/viewvc?rev=1808131&view=rev
Log:
BCEL-286: Utility.signatureToString fails if a method has multiple type arguments. Thanks to Mark Roberts.

Modified:
    commons/proper/bcel/trunk/src/changes/changes.xml
    commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/Utility.java
    commons/proper/bcel/trunk/src/test/java/org/apache/bcel/classfile/UtilityTestCase.java

Modified: commons/proper/bcel/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/changes/changes.xml?rev=1808131&r1=1808130&r2=1808131&view=diff
==============================================================================
--- commons/proper/bcel/trunk/src/changes/changes.xml [utf-8] (original)
+++ commons/proper/bcel/trunk/src/changes/changes.xml [utf-8] Tue Sep 12 16:36:55 2017
@@ -63,6 +63,7 @@ The <action> type attribute can be add,u
 
   <body>
     <release version="6.1" date="tba" description="tba">
+      <action issue="BCEL-286" type="fix" dev="britter" due-to="Mark Roberts">Utility.signatureToString fails if a method has multiple type arguments</action>
       <action issue="BCEL-287" type="fix" dev="britter" due-to="Mark Roberts">IINC does not handle -128 properly</action>
       <action issue="BCEL-283" type="fix" dev="britter" due-to="Mark Roberts">Support for StackMap should be different from StackMapTable</action>
       <action issue="BCEL-289" type="fix" dev="kinow">Crash when parsing constructor of inner classes with parameters annotated</action>

Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/Utility.java
URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/Utility.java?rev=1808131&r1=1808130&r2=1808131&view=diff
==============================================================================
--- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/Utility.java (original)
+++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/Utility.java Tue Sep 12 16:36:55 2017
@@ -849,6 +849,7 @@ public abstract class Utility {
                     if (index < 0) {
                         throw new ClassFormatException("Invalid signature: " + signature);
                     }
+
                     // check to see if there are any TypeArguments
                     final int bracketIndex = signature.substring(0, index).indexOf('<');
                     if (bracketIndex < 0) {
@@ -856,6 +857,16 @@ public abstract class Utility {
                         wrap(consumed_chars, index + 1); // "Lblabla;" `L' and `;' are removed
                         return compactClassName(signature.substring(1, index), chopit);
                     }
+                    // but make sure we are not looking past the end of the current item
+                    fromIndex = signature.indexOf(';');
+                    if (fromIndex < 0) {
+                        throw new ClassFormatException("Invalid signature: " + signature);
+                    }
+                    if (fromIndex < bracketIndex) {
+                        // just a class identifier
+                        wrap(consumed_chars, fromIndex + 1); // "Lblabla;" `L' and `;' are removed
+                        return compactClassName(signature.substring(1, fromIndex), chopit);
+                    }
 
                     // we have TypeArguments; build up partial result
                     // as we recurse for each TypeArgument
@@ -869,37 +880,63 @@ public abstract class Utility {
                     } else if (signature.charAt(consumed_chars) == '-') {
                         type.append("? super ");
                         consumed_chars++;
-                    } else if (signature.charAt(consumed_chars) == '*') {
-                        // must be at end of signature
-                        if (signature.charAt(consumed_chars + 1) != '>') {
-                            throw new ClassFormatException("Invalid signature: " + signature);
-                        }
-                        if (signature.charAt(consumed_chars + 2) != ';') {
-                            throw new ClassFormatException("Invalid signature: " + signature);
-                        }
-                        wrap(Utility.consumed_chars, consumed_chars + 3); // remove final "*>;"
-                        return type + "?>...";
                     }
 
                     // get the first TypeArgument
-                    type.append(signatureToString(signature.substring(consumed_chars), chopit));
-                    // update our consumed count by the number of characters the for type argument
-                    consumed_chars = unwrap(Utility.consumed_chars) + consumed_chars;
-                    wrap(Utility.consumed_chars, consumed_chars);
+                    if (signature.charAt(consumed_chars) == '*') {
+                        type.append("?");
+                        consumed_chars++;
+                    } else {
+                        type.append(signatureToString(signature.substring(consumed_chars), chopit));
+                        // update our consumed count by the number of characters the for type argument
+                        consumed_chars = unwrap(Utility.consumed_chars) + consumed_chars;
+                        wrap(Utility.consumed_chars, consumed_chars);
+                    }
 
                     // are there more TypeArguments?
                     while (signature.charAt(consumed_chars) != '>') {
-                        type.append(", ").append(signatureToString(signature.substring(consumed_chars), chopit));
+                        type.append(", ");
+                        // check for wildcards
+                        if (signature.charAt(consumed_chars) == '+') {
+                            type.append("? extends ");
+                            consumed_chars++;
+                        } else if (signature.charAt(consumed_chars) == '-') {
+                            type.append("? super ");
+                            consumed_chars++;
+                        }
+                        if (signature.charAt(consumed_chars) == '*') {
+                            type.append("?");
+                            consumed_chars++;
+                        } else {
+                            type.append(signatureToString(signature.substring(consumed_chars), chopit));
+                            // update our consumed count by the number of characters the for type argument
+                            consumed_chars = unwrap(Utility.consumed_chars) + consumed_chars;
+                            wrap(Utility.consumed_chars, consumed_chars);
+                        }
+                    }
+
+                    // process the closing ">"
+                    consumed_chars++;
+                    type.append(">");
+
+                    if (signature.charAt(consumed_chars) == '.') {
+                        // we have a ClassTypeSignatureSuffix
+                        type.append(".");
+                        // convert SimpleClassTypeSignature to fake ClassTypeSignature
+                        // and then recurse to parse it
+                        type.append(signatureToString("L" + signature.substring(consumed_chars+1), chopit));
                         // update our consumed count by the number of characters the for type argument
+                        // note that this count includes the "L" we added, but that is ok
+                        // as it accounts for the "." we didn't consume
                         consumed_chars = unwrap(Utility.consumed_chars) + consumed_chars;
                         wrap(Utility.consumed_chars, consumed_chars);
+                        return type.toString();
                     }
-
-                    if (signature.charAt(consumed_chars + 1) != ';') {
+                    if (signature.charAt(consumed_chars) != ';') {
                         throw new ClassFormatException("Invalid signature: " + signature);
                     }
-                    wrap(Utility.consumed_chars, consumed_chars + 2); // remove final ">;"
-                    return type.append(">").toString();
+                    wrap(Utility.consumed_chars, consumed_chars + 1); // remove final ";"
+                    return type.toString();
                 }
                 case 'S':
                     return "short";

Modified: commons/proper/bcel/trunk/src/test/java/org/apache/bcel/classfile/UtilityTestCase.java
URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/test/java/org/apache/bcel/classfile/UtilityTestCase.java?rev=1808131&r1=1808130&r2=1808131&view=diff
==============================================================================
--- commons/proper/bcel/trunk/src/test/java/org/apache/bcel/classfile/UtilityTestCase.java (original)
+++ commons/proper/bcel/trunk/src/test/java/org/apache/bcel/classfile/UtilityTestCase.java Tue Sep 12 16:36:55 2017
@@ -22,6 +22,7 @@ import junit.framework.TestCase;
 public class UtilityTestCase extends TestCase {
 
     public void testSignatureToStringWithGenerics() throws Exception {
+    // tests for BCEL-197
         assertEquals("generic signature",
                 "java.util.Map<X, java.util.List<Y>>",
                 Utility.signatureToString("Ljava/util/Map<TX;Ljava/util/List<TY;>;>;"));
@@ -29,7 +30,17 @@ public class UtilityTestCase extends Tes
                 "java.util.Set<? extends java.nio.file.OpenOption>"
                 , Utility.signatureToString("Ljava/util/Set<+Ljava/nio/file/OpenOption;>;"));
         assertEquals("generic signature",
-                "java.nio.file.attribute.FileAttribute<?>...[]",
+                "java.nio.file.attribute.FileAttribute<?>[]",
                 Utility.signatureToString("[Ljava/nio/file/attribute/FileAttribute<*>;"));
+    // tests for BCEL-286
+        assertEquals("generic signature",
+                "boofcv.alg.tracker.tld.TldTracker<boofcv.struct.image.ImageGray<boofcv.struct.image.GrayU8>, boofcv.struct.image.GrayI<boofcv.struct.image.GrayU8>>",
+                Utility.signatureToString("Lboofcv/alg/tracker/tld/TldTracker<Lboofcv/struct/image/ImageGray<Lboofcv/struct/image/GrayU8;>;Lboofcv/struct/image/GrayI<Lboofcv/struct/image/GrayU8;>;>;"));
+        assertEquals("generic signature",
+                "java.util.Map<?, ?>",
+                Utility.signatureToString("Ljava/util/Map<**>;"));
+        assertEquals("generic signature",
+                "com.jme3.util.IntMap<T>.IntMapIterator",
+                Utility.signatureToString("Lcom/jme3/util/IntMap<TT;>.IntMapIterator;"));
     }
 }