summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoman Shevchenko <roman.shevchenko@jetbrains.com>2014-09-12 17:26:03 +0400
committerRoman Shevchenko <roman.shevchenko@jetbrains.com>2014-09-12 17:30:26 +0400
commite90f1de039b9305eed038f58db773ac2b8be36ed (patch)
treec9d4b09f7f8b4f545b95f35278ead7c3c76d2569
parente2f7d09f3773af1ecf2b0e6b8e44a86a43906425 (diff)
downloadfernflower-e90f1de039b9305eed038f58db773ac2b8be36ed.tar
fernflower-e90f1de039b9305eed038f58db773ac2b8be36ed.tar.gz
fernflower-e90f1de039b9305eed038f58db773ac2b8be36ed.tar.lz
fernflower-e90f1de039b9305eed038f58db773ac2b8be36ed.tar.xz
fernflower-e90f1de039b9305eed038f58db773ac2b8be36ed.zip
IDEA-129221 (tolerate invalid signature attributes)
-rw-r--r--src/org/jetbrains/java/decompiler/main/ClassWriter.java14
-rw-r--r--src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMain.java116
-rw-r--r--test/org/jetbrains/java/decompiler/SingleClassesTest.java42
-rw-r--r--testData/classes/InvalidMethodSignature.classbin0 -> 761 bytes
-rw-r--r--testData/results/InvalidMethodSignature.dec26
5 files changed, 122 insertions, 76 deletions
diff --git a/src/org/jetbrains/java/decompiler/main/ClassWriter.java b/src/org/jetbrains/java/decompiler/main/ClassWriter.java
index 63f60ba..856ad22 100644
--- a/src/org/jetbrains/java/decompiler/main/ClassWriter.java
+++ b/src/org/jetbrains/java/decompiler/main/ClassWriter.java
@@ -626,12 +626,14 @@ public class ClassWriter {
StructGenericSignatureAttribute attr = (StructGenericSignatureAttribute)mt.getAttributes().getWithKey("Signature");
if (attr != null) {
descriptor = GenericMain.parseMethodSignature(attr.getSignature());
- int actualParams = md.params.length;
- if (isEnum && init) actualParams -= 2;
- if (actualParams != descriptor.params.size()) {
- String message = "Inconsistent generic signature in method " + mt.getName() + " " + mt.getDescriptor();
- DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.Severity.WARN);
- descriptor = null;
+ if (descriptor != null) {
+ int actualParams = md.params.length;
+ if (isEnum && init) actualParams -= 2;
+ if (actualParams != descriptor.params.size()) {
+ String message = "Inconsistent generic signature in method " + mt.getName() + " " + mt.getDescriptor();
+ DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.Severity.WARN);
+ descriptor = null;
+ }
}
}
}
diff --git a/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMain.java b/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMain.java
index 065029d..3082eca 100644
--- a/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMain.java
+++ b/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMain.java
@@ -17,6 +17,7 @@ package org.jetbrains.java.decompiler.struct.gen.generics;
import org.jetbrains.java.decompiler.code.CodeConstants;
import org.jetbrains.java.decompiler.main.DecompilerContext;
+import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger;
import org.jetbrains.java.decompiler.struct.StructClass;
import java.util.ArrayList;
@@ -24,7 +25,7 @@ import java.util.List;
public class GenericMain {
- private static final String[] typeNames = new String[]{
+ private static final String[] typeNames = {
"byte",
"char",
"double",
@@ -36,63 +37,80 @@ public class GenericMain {
};
public static GenericClassDescriptor parseClassSignature(String signature) {
+ String original = signature;
+ try {
+ GenericClassDescriptor descriptor = new GenericClassDescriptor();
- GenericClassDescriptor descriptor = new GenericClassDescriptor();
+ signature = parseFormalParameters(signature, descriptor.fparameters, descriptor.fbounds);
- signature = parseFormalParameters(signature, descriptor.fparameters, descriptor.fbounds);
+ String superCl = GenericType.getNextType(signature);
+ descriptor.superclass = new GenericType(superCl);
- String supercl = GenericType.getNextType(signature);
- descriptor.superclass = new GenericType(supercl);
+ signature = signature.substring(superCl.length());
+ while (signature.length() > 0) {
+ String superIf = GenericType.getNextType(signature);
+ descriptor.superinterfaces.add(new GenericType(superIf));
+ signature = signature.substring(superIf.length());
+ }
- signature = signature.substring(supercl.length());
- while (signature.length() > 0) {
- String superintr = GenericType.getNextType(signature);
- descriptor.superinterfaces.add(new GenericType(superintr));
- signature = signature.substring(superintr.length());
+ return descriptor;
+ }
+ catch (RuntimeException e) {
+ DecompilerContext.getLogger().writeMessage("Invalid signature: " + original, IFernflowerLogger.Severity.WARN);
+ return null;
}
-
- return descriptor;
}
public static GenericFieldDescriptor parseFieldSignature(String signature) {
- GenericFieldDescriptor descriptor = new GenericFieldDescriptor();
- descriptor.type = new GenericType(signature);
- return descriptor;
+ try {
+ GenericFieldDescriptor descriptor = new GenericFieldDescriptor();
+ descriptor.type = new GenericType(signature);
+ return descriptor;
+ }
+ catch (RuntimeException e) {
+ DecompilerContext.getLogger().writeMessage("Invalid signature: " + signature, IFernflowerLogger.Severity.WARN);
+ return null;
+ }
}
public static GenericMethodDescriptor parseMethodSignature(String signature) {
+ String original = signature;
+ try {
+ GenericMethodDescriptor descriptor = new GenericMethodDescriptor();
- GenericMethodDescriptor descriptor = new GenericMethodDescriptor();
-
- signature = parseFormalParameters(signature, descriptor.fparameters, descriptor.fbounds);
+ signature = parseFormalParameters(signature, descriptor.fparameters, descriptor.fbounds);
- int to = signature.indexOf(")");
- String pars = signature.substring(1, to);
- signature = signature.substring(to + 1);
+ int to = signature.indexOf(")");
+ String pars = signature.substring(1, to);
+ signature = signature.substring(to + 1);
- while (pars.length() > 0) {
- String par = GenericType.getNextType(pars);
- descriptor.params.add(new GenericType(par));
- pars = pars.substring(par.length());
- }
+ while (pars.length() > 0) {
+ String par = GenericType.getNextType(pars);
+ descriptor.params.add(new GenericType(par));
+ pars = pars.substring(par.length());
+ }
- String par = GenericType.getNextType(signature);
- descriptor.ret = new GenericType(par);
- signature = signature.substring(par.length());
+ String par = GenericType.getNextType(signature);
+ descriptor.ret = new GenericType(par);
+ signature = signature.substring(par.length());
- if (signature.length() > 0) {
- String[] excs = signature.split("\\^");
+ if (signature.length() > 0) {
+ String[] exceptions = signature.split("\\^");
- for (int i = 1; i < excs.length; i++) {
- descriptor.exceptions.add(new GenericType(excs[i]));
+ for (int i = 1; i < exceptions.length; i++) {
+ descriptor.exceptions.add(new GenericType(exceptions[i]));
+ }
}
- }
- return descriptor;
+ return descriptor;
+ }
+ catch (RuntimeException e) {
+ DecompilerContext.getLogger().writeMessage("Invalid signature: " + original, IFernflowerLogger.Severity.WARN);
+ return null;
+ }
}
- private static String parseFormalParameters(String signature, List<String> fparameters, List<List<GenericType>> fbounds) {
-
+ private static String parseFormalParameters(String signature, List<String> parameters, List<List<GenericType>> bounds) {
if (signature.charAt(0) != '<') {
return signature;
}
@@ -120,10 +138,10 @@ public class GenericMain {
signature = signature.substring(index + 1);
while (value.length() > 0) {
- int parto = value.indexOf(":");
+ int to = value.indexOf(":");
- String param = value.substring(0, parto);
- value = value.substring(parto + 1);
+ String param = value.substring(0, to);
+ value = value.substring(to + 1);
List<GenericType> lstBounds = new ArrayList<GenericType>();
@@ -146,8 +164,8 @@ public class GenericMain {
}
}
- fparameters.add(param);
- fbounds.add(lstBounds);
+ parameters.add(param);
+ bounds.add(lstBounds);
}
return signature;
@@ -162,8 +180,7 @@ public class GenericMain {
return s;
}
- public static String getTypeName(GenericType type) {
-
+ private static String getTypeName(GenericType type) {
int tp = type.type;
if (tp <= CodeConstants.TYPE_BOOLEAN) {
return typeNames[tp];
@@ -197,9 +214,9 @@ public class GenericMain {
}
}
- GenericType genpar = type.getArguments().get(i);
- if (genpar != null) {
- buffer.append(getGenericCastTypeName(genpar));
+ GenericType genPar = type.getArguments().get(i);
+ if (genPar != null) {
+ buffer.append(getGenericCastTypeName(genPar));
}
}
buffer.append(">");
@@ -208,11 +225,10 @@ public class GenericMain {
return buffer.toString();
}
- throw new RuntimeException("invalid type");
+ throw new RuntimeException("Invalid type: " + type);
}
- public static String buildJavaClassName(GenericType type) {
-
+ private static String buildJavaClassName(GenericType type) {
String name = "";
for (GenericType tp : type.getEnclosingClasses()) {
name += tp.value + "$";
diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java
index 6261591..70aa605 100644
--- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java
+++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java
@@ -43,30 +43,32 @@ public class SingleClassesTest {
fixture = null;
}
- @Test public void testClassFields() { doTest("TestClassFields"); }
- @Test public void testClassLambda() { doTest("TestClassLambda"); }
- @Test public void testClassLoop() { doTest("TestClassLoop"); }
- @Test public void testClassSwitch() { doTest("TestClassSwitch"); }
- @Test public void testClassTypes() { doTest("TestClassTypes"); }
- @Test public void testClassVar() { doTest("TestClassVar"); }
- @Test public void testClassNestedInitializer() { doTest("TestClassNestedInitializer"); }
- @Test public void testClassCast() { doTest("TestClassCast"); }
- @Test public void testDeprecations() { doTest("TestDeprecations"); }
- @Test public void testExtendsList() { doTest("TestExtendsList"); }
- @Test public void testMethodParameters() { doTest("TestMethodParameters"); }
- @Test public void testCodeConstructs() { doTest("TestCodeConstructs"); }
- @Test public void testConstants() { doTest("TestConstants"); }
- @Test public void testEnum() { doTest("TestEnum"); }
- @Test public void testDebugSymbols() { doTest("TestDebugSymbols"); }
-
- private void doTest(final String testName) {
+ @Test public void testClassFields() { doTest("pkg/TestClassFields"); }
+ @Test public void testClassLambda() { doTest("pkg/TestClassLambda"); }
+ @Test public void testClassLoop() { doTest("pkg/TestClassLoop"); }
+ @Test public void testClassSwitch() { doTest("pkg/TestClassSwitch"); }
+ @Test public void testClassTypes() { doTest("pkg/TestClassTypes"); }
+ @Test public void testClassVar() { doTest("pkg/TestClassVar"); }
+ @Test public void testClassNestedInitializer() { doTest("pkg/TestClassNestedInitializer"); }
+ @Test public void testClassCast() { doTest("pkg/TestClassCast"); }
+ @Test public void testDeprecations() { doTest("pkg/TestDeprecations"); }
+ @Test public void testExtendsList() { doTest("pkg/TestExtendsList"); }
+ @Test public void testMethodParameters() { doTest("pkg/TestMethodParameters"); }
+ @Test public void testCodeConstructs() { doTest("pkg/TestCodeConstructs"); }
+ @Test public void testConstants() { doTest("pkg/TestConstants"); }
+ @Test public void testEnum() { doTest("pkg/TestEnum"); }
+ @Test public void testDebugSymbols() { doTest("pkg/TestDebugSymbols"); }
+ @Test public void testInvalidMethodSignature() { doTest("InvalidMethodSignature"); }
+
+ private void doTest(String testFile) {
try {
- File classFile = new File(fixture.getTestDataDir(), "/classes/pkg/" + testName + ".class");
+ File classFile = new File(fixture.getTestDataDir(), "/classes/" + testFile + ".class");
assertTrue(classFile.isFile());
+ String testName = classFile.getName().replace(".class", "");
ConsoleDecompiler decompiler = fixture.getDecompiler();
- for (File inner : collectClasses(classFile)) {
- decompiler.addSpace(inner, true);
+ for (File file : collectClasses(classFile)) {
+ decompiler.addSpace(file, true);
}
decompiler.decompileContext();
diff --git a/testData/classes/InvalidMethodSignature.class b/testData/classes/InvalidMethodSignature.class
new file mode 100644
index 0000000..3b64eb8
--- /dev/null
+++ b/testData/classes/InvalidMethodSignature.class
Binary files differ
diff --git a/testData/results/InvalidMethodSignature.dec b/testData/results/InvalidMethodSignature.dec
new file mode 100644
index 0000000..3b1bee4
--- /dev/null
+++ b/testData/results/InvalidMethodSignature.dec
@@ -0,0 +1,26 @@
+package a.a.a.a.e.f;
+
+import a.a.a.a.a.k;
+import a.a.a.a.c.c;
+import a.a.a.a.c.j;
+import a.a.a.a.e.bg;
+import a.a.a.a.e.f.b;
+import java.io.File;
+
+class i implements bg {
+ private final j a;
+ private final b b;
+
+ i(b var1, j var2) {
+ this.b = var1;
+ this.a = var2;
+ }
+
+ public void a(c var1, k var2, boolean var3) {
+ File var4 = this.a.b().a(var1);
+ b.a(this.b).add(var4);
+ }
+
+ public void a(a.a.a.a.c.b var1) {
+ }
+}