From: Andy Clement Date: Wed, 1 Apr 2015 15:02:01 +0000 (-0700) Subject: 406167: cope with rogue generic inner type signatures X-Git-Tag: V1_8_6~11 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=c6753a8aaf104ddd8e3d50ea493ea3ab579fc2fc;p=aspectj.git 406167: cope with rogue generic inner type signatures --- diff --git a/util/src/org/aspectj/util/GenericSignatureParser.java b/util/src/org/aspectj/util/GenericSignatureParser.java index 3f11662f6..28c8db83d 100644 --- a/util/src/org/aspectj/util/GenericSignatureParser.java +++ b/util/src/org/aspectj/util/GenericSignatureParser.java @@ -187,18 +187,10 @@ public class GenericSignatureParser { // now we have either a "." indicating the start of a nested type, // or a "<" indication type arguments, or ";" and we are done. while (!maybeEat(";")) { - if (maybeEat(".")) { + if (tokenStream[tokenIndex].equals(".")) { // outer type completed outerType = new SimpleClassTypeSignature(identifier); - List nestedTypeList = new ArrayList(); - do { - ret.append("."); - SimpleClassTypeSignature sig = parseSimpleClassTypeSignature(); - ret.append(sig.toString()); - nestedTypeList.add(sig); - } while (maybeEat(".")); - nestedTypes = new SimpleClassTypeSignature[nestedTypeList.size()]; - nestedTypeList.toArray(nestedTypes); + nestedTypes = parseNestedTypesHelper(ret); } else if (tokenStream[tokenIndex].equals("<")) { ret.append("<"); TypeArgument[] tArgs = maybeParseTypeArguments(); @@ -207,16 +199,7 @@ public class GenericSignatureParser { } ret.append(">"); outerType = new SimpleClassTypeSignature(identifier, tArgs); - // now parse possible nesteds... - List nestedTypeList = new ArrayList(); - while (maybeEat(".")) { - ret.append("."); - SimpleClassTypeSignature sig = parseSimpleClassTypeSignature(); - ret.append(sig.toString()); - nestedTypeList.add(sig); - } - nestedTypes = new SimpleClassTypeSignature[nestedTypeList.size()]; - nestedTypeList.toArray(nestedTypes); + nestedTypes = parseNestedTypesHelper(ret); } else { throw new IllegalStateException("Expecting .,<, or ;, but found " + tokenStream[tokenIndex] + " while unpacking " + inputString); @@ -228,6 +211,39 @@ public class GenericSignatureParser { return new ClassTypeSignature(ret.toString(), outerType, nestedTypes); } + /** + * Helper method to digest nested types, slightly more complex than necessary to cope with some android related + * incorrect classes (see bug 406167) + */ + private SimpleClassTypeSignature[] parseNestedTypesHelper(StringBuffer ret) { + boolean brokenSignature = false; + SimpleClassTypeSignature[] nestedTypes; + List nestedTypeList = new ArrayList(); + while (maybeEat(".")) { + ret.append("."); + SimpleClassTypeSignature sig = parseSimpleClassTypeSignature(); + if (tokenStream[tokenIndex].equals("/")) { + if (!brokenSignature) { + System.err.println("[See bug 406167] Bad class file signature encountered, nested types appear package qualified, ignoring those incorrect pieces. Signature: "+inputString); + } + brokenSignature = true; + // hit something like: Lcom/a/a/b/t.com/a/a/b/af.com/a/a/b/ag; + // and we are looking at the '/' after the com + tokenIndex++; // pointing at the next identifier + while (tokenStream[tokenIndex+1].equals("/")) { + tokenIndex+=2; // jump over an 'identifier' '/' pair + } + // now tokenIndex is the final bit of the name (which we'll treat as the inner type name) + sig = parseSimpleClassTypeSignature(); + } + ret.append(sig.toString()); + nestedTypeList.add(sig); + }; + nestedTypes = new SimpleClassTypeSignature[nestedTypeList.size()]; + nestedTypeList.toArray(nestedTypes); + return nestedTypes; + } + private SimpleClassTypeSignature parseSimpleClassTypeSignature() { String identifier = eatIdentifier(); TypeArgument[] tArgs = maybeParseTypeArguments(); diff --git a/util/testsrc/org/aspectj/util/GenericSignatureParserTest.java b/util/testsrc/org/aspectj/util/GenericSignatureParserTest.java index c46c97b63..5a9e083e4 100644 --- a/util/testsrc/org/aspectj/util/GenericSignatureParserTest.java +++ b/util/testsrc/org/aspectj/util/GenericSignatureParserTest.java @@ -95,6 +95,27 @@ public class GenericSignatureParserTest extends TestCase { assertEquals("Ljava/util/Comparable<-TE;>;", sig.superInterfaceSignatures[0].toString()); } + public void testFunky_406167() { + ClassSignature sig = parser + .parseAsClassSignature("Lcom/google/android/gms/internal/hb.com/google/android/gms/internal/hb$b;"); + // Note the package prefix on the nested types has been dropped + assertEquals("Lcom/google/android/gms/internal/hb.hb$b;",sig.superclassSignature.toString()); + sig = parser + .parseAsClassSignature("Lcom/a/a/b/t.com/a/a/b/af.com/a/a/b/ag;Ljava/util/ListIterator;"); + // Note the package prefix on the nested types has been dropped + assertEquals("Lcom/a/a/b/t.af.ag;",sig.superclassSignature.toString()); + assertEquals("Ljava/util/ListIterator;",sig.superInterfaceSignatures[0].toString()); + sig = parser.parseAsClassSignature("Lcom/google/android/gms/internal/hb.com/google/android/gms/internal/hb$b;"); + // Note the package prefix on the nested types has been dropped + assertEquals("Lcom/google/android/gms/internal/hb.hb$b;",sig.superclassSignature.toString()); + sig = parser + .parseAsClassSignature("Lcom/a/a/b/t.com/a/a/b/af.com/a/a/b/ag;Ljava/util/ListIterator;"); + // Note the package prefix on the nested types has been dropped + assertEquals("Lcom/a/a/b/t.af.ag;",sig.superclassSignature.toString()); + assertEquals("Ljava/util/ListIterator;",sig.superInterfaceSignatures[0].toString()); + } + + public void testFieldSignatureParsingClassType() { FieldTypeSignature fsig = parser.parseAsFieldSignature("Ljava/lang/String;"); assertTrue("ClassTypeSignature", fsig instanceof ClassTypeSignature); @@ -155,7 +176,7 @@ public class GenericSignatureParserTest extends TestCase { assertEquals("Ljava/lang/Exception;", mSig.throwsSignatures[0].toString()); assertEquals("Ljava/lang/RuntimeException;", mSig.throwsSignatures[1].toString()); } - + public void testMethodSignaturePrimitiveParams() { GenericSignature.MethodTypeSignature mSig = parser.parseAsMethodSignature("(ILjava/lang/Object;)V"); assertEquals("2 parameters", 2, mSig.parameters.length);