Add jadx-gui, restructure src directory

This commit is contained in:
Skylot
2013-07-10 22:57:39 +04:00
parent cbbb73355b
commit ce7d6f0156
168 changed files with 1533 additions and 1041 deletions
@@ -0,0 +1,39 @@
package jadx.samples;
public abstract class AbstractTest {
public abstract boolean testRun() throws Exception;
public static void assertTrue(boolean condition) {
if (!condition) {
throw new AssertionError();
}
}
public static void assertFalse(boolean condition) {
if (condition) {
throw new AssertionError();
}
}
public static void assertTrue(boolean condition, String msg) {
if (!condition) {
throw new AssertionError(msg);
}
}
public static void assertEquals(int a1, int a2) {
if (a1 != a2) {
throw new AssertionError(a1 + " != " + a2);
}
}
public static void assertEquals(Object a1, Object a2) {
if (a1 == null) {
if (a2 != null)
throw new AssertionError(a1 + " != " + a2);
} else if (!a1.equals(a2)) {
throw new AssertionError(a1 + " != " + a2);
}
}
}
@@ -0,0 +1,113 @@
package jadx.samples;
import java.io.File;
import java.io.FilenameFilter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
public class RunTests {
public static void main(String[] args) {
ClassLoader clsLoader = ClassLoader.getSystemClassLoader();
List<String> clsList = getClasses(clsLoader, "jadx.samples");
if (clsList.isEmpty()) {
System.err.println("No tests found");
System.exit(1);
}
int timeout = 2 * clsList.size();
System.err.println("Set timeout to " + timeout + " seconds");
new Timer().schedule(new TerminateTask(), timeout * 1000);
Collections.sort(clsList);
int passed = 0;
for (String cls : clsList) {
if (runTest(cls))
passed++;
}
int failed = clsList.size() - passed;
System.err.println("---");
System.err.println("Total " + clsList.size()
+ ", Passed: " + passed
+ ", Failed: " + failed);
System.exit(failed);
}
private static boolean runTest(String clsName) {
try {
boolean pass = false;
String msg = null;
Throwable exc = null;
Class<?> cls = Class.forName(clsName);
if (cls.getSuperclass() == AbstractTest.class) {
Method mth = cls.getMethod("testRun");
try {
AbstractTest test = (AbstractTest) cls.getConstructor().newInstance();
pass = (Boolean) mth.invoke(test);
} catch (InvocationTargetException e) {
pass = false;
exc = e.getCause();
} catch (Throwable e) {
pass = false;
exc = e;
}
} else {
msg = "not extends AbstractTest";
}
System.err.println(">> "
+ (pass ? "PASS" : "FAIL") + "\t"
+ clsName
+ (msg == null ? "" : "\t - " + msg));
if (exc != null)
exc.printStackTrace();
return pass;
} catch (ClassNotFoundException e) {
System.err.println("Class '" + clsName + "' not found");
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
private static class TerminateTask extends TimerTask {
@Override
public void run() {
System.err.println("Test timed out");
System.exit(1);
}
}
private static class TestFilter implements FilenameFilter {
@Override
public boolean accept(File dir, String name) {
return name.startsWith("Test") && name.endsWith(".class") && !name.contains("$");
}
}
private static List<String> getClasses(ClassLoader clsLoader, String packageName) {
List<String> clsList = new ArrayList<String>();
URL resource = clsLoader.getResource(packageName.replace('.', '/'));
if (resource != null) {
File path = new File(resource.getFile());
if (path.exists() && path.isDirectory()) {
System.out.println("Test classes path: " + path.getAbsolutePath());
String[] files = path.list(new TestFilter());
for (String file : files) {
String clsName = packageName + '.' + file.replace(".class", "");
clsList.add(clsName);
}
}
}
return clsList;
}
}
@@ -0,0 +1,102 @@
package jadx.samples;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
import java.util.Arrays;
public class TestAnnotations extends AbstractTest {
@Deprecated
public int a;
public void error() throws Exception {
throw new Exception("error");
}
@Deprecated
public static Object depr(String[] a) {
return Arrays.asList(a);
}
public @interface SimpleAnnotation {
boolean value();
}
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
String name() default "a";
String str() default "str";
int num();
float value();
double[] doubles();
Class<?> cls();
SimpleAnnotation simple();
Thread.State state() default Thread.State.TERMINATED;
}
@MyAnnotation(name = "b",
num = 7,
cls = Exception.class,
doubles = { 0.0, 1.1 },
value = 9.87f,
simple = @SimpleAnnotation(false))
public static Object test(String[] a) {
return Arrays.asList(a);
}
public static Object test2(@Deprecated String a, @SimpleAnnotation(value = false) Object b) {
@Deprecated
Object c = a;
return c;
}
public @interface ClassesAnnotation {
Class<?>[] value();
}
@ClassesAnnotation({
int.class, int[].class, int[][][].class,
String.class, String[].class, String[][].class
})
public static Object test3(Object b) {
return b.toString();
}
@Override
public boolean testRun() throws Exception {
Class<?> cls = TestAnnotations.class;
new Thread();
Method err = cls.getMethod("error");
assertTrue(err.getExceptionTypes().length > 0);
assertTrue(err.getExceptionTypes()[0] == Exception.class);
Method d = cls.getMethod("depr", String[].class);
assertTrue(d.getAnnotations().length > 0);
assertTrue(d.getAnnotations()[0].annotationType() == Deprecated.class);
Method ma = cls.getMethod("test", String[].class);
assertTrue(ma.getAnnotations().length > 0);
MyAnnotation a = (MyAnnotation) ma.getAnnotations()[0];
assertTrue(a.num() == 7);
assertTrue(a.state() == Thread.State.TERMINATED);
return true;
}
public static void main(String[] args) throws Exception {
new TestAnnotations().testRun();
}
}
@@ -0,0 +1,34 @@
package jadx.samples;
public class TestArrays extends AbstractTest {
public int test1(int i) {
// fill-array-data
int[] a = new int[] { 1, 2, 3, 5 };
return a[i];
}
public int test2(int i) {
// filled-new-array
int[][] a = new int[i][i + 1];
return a.length;
}
public int test3(int i) {
// filled-new-array/range
boolean[][][][][][][][] a = new boolean[i][i][i][i][i][i][i][i];
return a.length;
}
@Override
public boolean testRun() throws Exception {
assertEquals(test1(2), 3);
assertEquals(test2(2), 2);
assertEquals(test3(2), 2);
return true;
}
public static void main(String[] args) throws Exception {
new TestArrays().testRun();
}
}
@@ -0,0 +1,217 @@
package jadx.samples;
public class TestCF extends AbstractTest {
public int test1(int a) {
if (a > 0) {
return 1;
} else {
a += 2;
return a * 3;
}
}
public int test1a(int a) {
if (a > 0) {
a++;
}
a *= 2;
return a + 3;
}
public int test1b(int a) {
if (a > 0) {
if (a < 5)
a++;
else
a -= 2;
}
a *= 2;
return a + 3;
}
public int test1c(int a, int b) {
if (a > 0) {
long c = 5;
a = (int) (a + c);
} else {
double f = 7.7;
a *= f;
}
return a + b;
}
public int test2(int a, int b) {
int c = a + b;
for (int i = a; i < b; i++) {
c *= 2;
}
c--;
return c;
}
public int test2a(int a, int b) {
int c = a + b;
for (int i = a; i < b; i++) {
if (i == 7) {
c += 2;
} else {
c *= 2;
}
}
c--;
return c;
}
public int test3(int a, int b) {
int c = 0;
for (int i = a; i < b; i++) {
int z = a * i + 5;
if (i == 7) {
c += z + a;
} else {
c *= z + b;
}
}
return c;
}
public int test4(int a, int b) {
int c = 0;
for (int i = a; i < b; i++) {
int z = (i == 7 ? a : b);
c *= z + b;
if (i == 7) {
c += z + a;
} else {
c *= z + b;
}
}
return c;
}
public int test5(int a, int b) {
int c = b;
do {
int z = c + a;
if (z >= 7) {
break;
}
c = z;
} while (true);
return c;
}
public int test6(int a, int b) {
int c = b;
int z;
while ((z = c + a) >= 7) {
c = z;
}
return c;
}
public int test7(int a, int b) {
int c = b;
int z;
do {
z = c + a;
if (z >= 7) {
break;
}
c = z;
} while (true);
while ((z = c + a) >= 7) {
c = z;
}
return c;
}
public int testIfElse(String str) {
int r;
if (str.equals("a"))
r = 1;
else if (str.equals("b"))
r = 2;
else if (str.equals("3"))
r = 3;
else if (str.equals("$"))
r = 4;
else
r = -1;
r = r * 10;
return Math.abs(r);
}
public int testIfElse2(String str) {
String a;
if (str.length() == 5) {
a = new String("1");
a.trim();
a.length();
}
a = new String("22");
a.toLowerCase();
return a.length();
}
public void testInfiniteLoop() {
while (true) {
System.out.println("test");
}
}
public static void test_hello(String[] args) {
System.out.println("Hello world!");
}
public static void test_print(String[] args) {
for (String arg : args) {
System.out.println(arg);
}
}
@Override
public boolean testRun() throws Exception {
TestCF c = new TestCF();
assertEquals(c.test1(1), 1);
assertEquals(c.test1(-1), 3);
assertEquals(c.test1a(12), 29);
assertEquals(c.test1b(-1), 1);
assertEquals(c.test1b(3), 11);
assertEquals(c.test1b(12), 23);
assertEquals(c.test1c(-1, 1), -6);
assertEquals(c.test1c(3, 2), 10);
assertEquals(c.test2(2, 4), 23);
assertEquals(c.test2(6, 4), 9);
assertEquals(c.test2a(5, 9), 115);
assertEquals(c.test2a(8, 23), 1015807);
assertEquals(c.test3(5, 9), 2430);
assertEquals(c.test3(8, 23), 0);
assertEquals(c.test4(5, 9), 3240);
assertEquals(c.test4(8, 15), 0);
assertEquals(c.testIfElse("b"), 20);
assertEquals(c.testIfElse("c"), 10);
assertEquals(c.testIfElse2("12345"), 2);
return true;
}
public static void main(String[] args) throws Exception {
System.out.println("TestCF: " + new TestCF().testRun());
}
}
@@ -0,0 +1,115 @@
package jadx.samples;
public class TestCF2 extends AbstractTest {
private final Object ready_mutex = new Object();
private boolean ready = false;
public int simple_loops() throws InterruptedException {
int[] a = new int[] { 1, 2, 4, 6, 8 };
int b = 0;
for (int i = 0; i < a.length; i++) {
b += a[i];
}
for (long i = b; i > 0; i--) {
b += i;
}
return b;
}
/**
* Test infinite loop
*/
public void run() throws InterruptedException {
while (true) {
if (!ready)
ready_mutex.wait();
ready = false;
func();
}
}
private void func() {
ready = true;
}
public void do_while() throws InterruptedException {
int i = 3;
do {
func();
i++;
} while (i < 5);
}
public void do_while_2(long k) throws InterruptedException {
if (k > 5) {
long i = 3;
do {
func();
i++;
} while (i < 5);
}
}
public void do_while_3(int k) throws InterruptedException {
int i = 3;
do {
if (k > 9) {
func();
}
i++;
} while (i < 5);
}
public int do_while_break(int k) throws InterruptedException {
int i = 3;
do {
if (k > 9) {
i = 0;
break;
}
i++;
} while (i < 5);
return i;
}
public int do_while_continue(int k) throws InterruptedException {
int i = 0;
do {
if (k > 9) {
i = k + 1;
continue;
}
i++;
} while (i < k);
return i;
}
public void do_while_return2(boolean k) throws InterruptedException {
int i = 3;
do {
if (k)
return;
i++;
} while (i < 5);
}
public void while_iterator(String[] args, int k) throws InterruptedException {
for (String arg : args) {
if (arg.length() > 9) {
func();
}
}
}
@Override
public boolean testRun() throws Exception {
assertEquals(simple_loops(), 252);
// TODO add checks
return true;
}
public static void main(String[] args) throws Exception {
System.out.println("TestCF2: " + new TestCF2().testRun());
}
}
@@ -0,0 +1,167 @@
package jadx.samples;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
public class TestCF3 extends AbstractTest {
public String f = "str//ing";
private boolean enabled;
private void setEnabled(boolean b) {
this.enabled = b;
}
private int next() {
return 1;
}
private int exc() throws Exception {
return 1;
}
public void testSwitchInLoop() throws Exception {
while (true) {
int n = next();
switch (n) {
case 0:
setEnabled(false);
break;
case 1:
setEnabled(true);
return;
}
}
}
private void testIfInLoop() {
int j = 0;
for (int i = 0; i < f.length(); i++) {
char ch = f.charAt(i);
if (ch == '/') {
j++;
if (j == 2) {
setEnabled(true);
return;
}
}
}
setEnabled(false);
}
public boolean testNestedLoops(List<String> l1, List<String> l2) {
Iterator<String> it1 = l1.iterator();
while (it1.hasNext()) {
String s1 = it1.next();
Iterator<String> it2 = l2.iterator();
while (it2.hasNext()) {
String s2 = it2.next();
if (s1.equals(s2)) {
if (s1.length() == 5)
l2.add(s1);
else
l1.remove(s2);
}
}
}
if (l2.size() > 0)
l1.clear();
return l1.size() == 0;
}
public boolean testNestedLoops2(List<String> list) {
int i = 0;
int j = 0;
while (i < list.size()) {
String s = list.get(i);
while (j < s.length()) {
j++;
}
i++;
}
return j > 10;
}
public static boolean testLabeledBreakContinue() {
String searchMe = "Look for a substring in me";
String substring = "sub";
boolean foundIt = false;
// int max = searchMe.length() - substring.length();
// test: for (int i = 0; i <= max; i++) {
// int n = substring.length();
// int j = i;
// int k = 0;
// while (n-- != 0) {
// if (searchMe.charAt(j++) != substring.charAt(k++)) {
// continue test;
// }
// }
// foundIt = true;
// break test;
// }
// System.out.println(foundIt ? "Found it" : "Didn't find it");
return foundIt;
}
public String testReturnInLoop(List<String> list) {
Iterator<String> it = list.iterator();
while (it.hasNext()) {
String ver = it.next();
if (ver != null)
return ver;
}
return "error";
}
public String testReturnInLoop2(List<String> list) {
try {
Iterator<String> it = list.iterator();
while (it.hasNext()) {
String ver = it.next();
exc();
if (ver != null)
return ver;
}
} catch (Exception e) {
setEnabled(false);
}
return "error";
}
@Override
public boolean testRun() throws Exception {
setEnabled(false);
testSwitchInLoop();
assertTrue(enabled);
setEnabled(false);
testIfInLoop();
assertTrue(enabled);
assertTrue(testNestedLoops(
new ArrayList<String>(Arrays.asList("a1", "a2")),
new ArrayList<String>(Arrays.asList("a1", "b2"))));
List<String> list1 = Arrays.asList(null, "a", "b");
// TODO this line required to omit generic information because it create List<Object>
// List<String> list2 = Arrays.asList(null, null, null);
assertEquals(testReturnInLoop(list1), "a");
assertEquals(testReturnInLoop2(list1), "a");
// assertEquals(testReturnInLoop(list2), "error");
// assertEquals(testReturnInLoop2(list2), "error");
// assertTrue(testLabeledBreakContinue());
return true;
}
public static void main(String[] args) throws Exception {
new TestCF3().testRun();
}
}
@@ -0,0 +1,67 @@
package jadx.samples;
/**
* Failed tests for current jadx version
*/
public class TestConditions extends AbstractTest {
public int test1(int num) {
boolean inRange = (num >= 59 && num <= 66);
if (inRange) {
num++;
}
return num;
}
public int test1a(int num) {
boolean notInRange = (num < 59 || num > 66);
if (notInRange) {
num--;
}
return num;
}
public int test1b(int num) {
boolean inc = (num >= 59 && num <= 66 && num != 62);
if (inc) {
num++;
}
return num;
}
public boolean test1c(int num) {
return num == 4 || num == 6;
}
public boolean test2(int num) {
if(num == 4 || num == 6){
return String.valueOf(num).equals("4");
}
if(num == 5) {
return true;
}
return this.toString().equals("a");
}
@Override
public boolean testRun() throws Exception {
TestConditions c = new TestConditions();
assertEquals(c.test1(50), 50);
assertEquals(c.test1(60), 61);
assertEquals(c.test1a(50), 49);
assertEquals(c.test1a(60), 60);
assertEquals(c.test1b(60), 61);
assertEquals(c.test1b(62), 62);
assertTrue(c.test1c(4));
assertFalse(c.test1c(5));
return true;
}
public static void main(String[] args) throws Exception {
new TestConditions().testRun();
}
}
@@ -0,0 +1,15 @@
package jadx.samples;
public class TestDeadCode extends AbstractTest {
private void test1(int i) {
if (i == 0)
return;
return;
}
@Override
public boolean testRun() throws Exception {
return true;
}
}
@@ -0,0 +1,128 @@
package jadx.samples;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
public class TestEnum extends AbstractTest {
public enum Direction {
NORTH, SOUTH, EAST, WEST
};
private static int three = 3;
public enum Numbers {
ONE(1), TWO(2), THREE(three), FOUR(three + 1);
private final int num;
private Numbers(int n) {
this.num = n;
}
public int getNum() {
return num;
}
};
public enum Operation {
PLUS {
@Override
int apply(int x, int y) {
return x + y;
}
},
MINUS {
@Override
int apply(int x, int y) {
return x - y;
}
};
abstract int apply(int x, int y);
}
public interface IOps {
double apply(double x, double y);
}
public enum DoubleOperations implements IOps {
TIMES("*") {
@Override
public double apply(double x, double y) {
return x * y;
}
},
DIVIDE("/") {
@Override
public double apply(double x, double y) {
return x / y;
}
};
private final String op;
private DoubleOperations(String op) {
this.op = op;
}
public String getOp() {
return op;
}
}
public enum Types {
INT, FLOAT,
LONG, DOUBLE,
OBJECT, ARRAY;
private static Set<Types> primitives = EnumSet.of(INT, FLOAT, LONG, DOUBLE);
public static List<Types> references = new ArrayList<Types>();
static {
references.add(OBJECT);
references.add(ARRAY);
}
public static Set<Types> getPrimitives() {
return primitives;
}
}
public enum EmptyEnum {
;
public static String getOp() {
return "op";
}
}
public enum Singleton {
INSTANCE;
public String test(String arg) {
return arg.concat("test");
}
}
@Override
public boolean testRun() throws Exception {
Direction d = Direction.EAST;
assertTrue(d.toString().equals("EAST"));
assertTrue(d.ordinal() == 2);
assertTrue(Numbers.THREE.getNum() == 3);
assertTrue(Operation.PLUS.apply(2, 2) == 4);
assertTrue(DoubleOperations.TIMES.apply(1, 1) == 1);
assertTrue(Types.getPrimitives().contains(Types.INT));
assertTrue(Types.references.size() == 2);
assertTrue(EmptyEnum.values().length == 0);
assertTrue(EmptyEnum.getOp().equals("op"));
assertTrue(Singleton.INSTANCE.test("a").equals("atest"));
return true;
}
public static void main(String[] args) throws Exception {
new TestEnum().testRun();
}
}
@@ -0,0 +1,47 @@
package jadx.samples;
import java.util.Arrays;
public class TestFields extends AbstractTest {
public static class ConstFields {
public static final boolean BOOL = false;
public static final int CONST_INT = 56789;
public static final int ZERO = 0;
public static final String STR = "string";
public static final double PI = 3.14;
}
private static final boolean fbz = false;
private static final boolean fb = true;
private static final int fi = 5;
private static final int fiz = 0;
private static final String fstr = "final string";
private static final double fd = 3.14;
private static final double[] fda = new double[]{3.14, 2.7};
private static int si = 5;
public void testConstsFields() {
int r = ConstFields.CONST_INT;
r += ConstFields.BOOL ? 1 : 0;
r += ConstFields.ZERO * 5;
r += ConstFields.STR.length() + ConstFields.STR.indexOf('i');
r += Math.round(ConstFields.PI);
assertEquals(r, 56801);
}
@Override
public boolean testRun() throws Exception {
testConstsFields();
String str = "" + fbz + fiz + fb + fi + fstr + fd + Arrays.toString(fda) + si;
return str.equals("false0true5final string3.14[3.14, 2.7]5");
}
public static void main(String[] args) throws Exception {
new TestFields().testRun();
}
}
@@ -0,0 +1,193 @@
package jadx.samples;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class TestGenerics extends AbstractTest {
public List<String> strings;
public Class<?>[] classes;
public interface MyComparable<T> {
public int compareTo(T o);
}
public static class GenericClass implements MyComparable<String> {
@Override
public int compareTo(String o) {
return 0;
}
}
public static class Box<T> {
private T t;
public void set(T t) {
this.t = t;
}
public T get() {
return t;
}
}
public static Box<Integer> integerBox = new Box<Integer>();
public interface Pair<K, LongGenericType> {
public K getKey();
public LongGenericType getValue();
}
public static class OrderedPair<K, V> implements Pair<K, V> {
private final K key;
private final V value;
public OrderedPair(K key, V value) {
this.key = key;
this.value = value;
}
@Override
public K getKey() {
return key;
}
@Override
public V getValue() {
return value;
}
}
Pair<String, Integer> p1 = new OrderedPair<String, Integer>("8", 8);
OrderedPair<String, Box<Integer>> p = new OrderedPair<String, Box<Integer>>("primes", new Box<Integer>());
public static class Util {
// Generic static method
public static <K, V> boolean compare(Pair<K, V> p1, Pair<K, V> p2) {
return p1.getKey().equals(p2.getKey()) &&
p1.getValue().equals(p2.getValue());
}
}
public static boolean use() {
Pair<Integer, String> p1 = new OrderedPair<Integer, String>(1, "str1");
Pair<Integer, String> p2 = new OrderedPair<Integer, String>(2, "str2");
boolean same = Util.<Integer, String> compare(p1, p2);
return same;
}
public class NaturalNumber<T extends Integer> {
private final T n;
public NaturalNumber(T n) {
this.n = n;
}
public boolean isEven() {
return n.intValue() % 2 == 0;
}
}
class A {
}
interface B {
}
interface C {
}
class D<T extends A & B & C> {
}
public static <T extends Comparable<T>> int countGreaterThan(T[] anArray, T elem) {
int count = 0;
for (T e : anArray)
if (e.compareTo(elem) > 0)
++count;
return count;
}
public static void process(List<? extends A> list) {
}
public static void printList(List<?> list) {
for (Object elem : list)
System.out.print(elem + " ");
System.out.println();
}
public static void addNumbers(List<? super Integer> list) {
for (int i = 1; i <= 10; i++) {
list.add(i);
}
}
public class Node<T extends Comparable<T>> {
private final T data;
private final Node<T> next;
public Node(T data, Node<T> next) {
this.data = data;
this.next = next;
}
public T getData() {
return data;
}
}
private class TestConstructor implements Enumeration<String> {
private final TestGenerics a;
TestConstructor(TestGenerics a) {
this.a = a;
}
@Override
public boolean hasMoreElements() {
return false;
}
@Override
public String nextElement() {
return null;
}
}
public Enumeration<String> testThis() {
return new TestConstructor(this);
}
private List<String> test1(Map<String, String> map) {
List<String> list = new ArrayList<String>();
String str = map.get("key");
list.add(str);
return list;
}
public void test2(Map<String, String> map, List<Object> list) {
String str = map.get("key");
list.add(str);
}
public void test3(List<Object> list, int a, float[] b, String[] c, String[][][] d) {
}
@Override
public boolean testRun() throws Exception {
assertTrue(test1(new HashMap<String, String>()) != null);
// TODO: add other checks
return true;
}
public static void main(String[] args) throws Exception {
new TestGenerics().testRun();
}
}
@@ -0,0 +1,85 @@
package jadx.samples;
public class TestInner extends AbstractTest {
public static int count = -2;
public static class MyThread extends Thread {
public MyThread(String name) {
super(name);
}
@Override
public void run() {
count++;
super.run();
}
}
public static class MyInceptionThread extends MyThread {
public static class MyThread2 extends Thread {
@Override
public void run() {
count += 2;
}
}
public MyInceptionThread() {
super("MyInceptionThread");
}
@Override
public void run() {
MyThread2 thr = new MyThread2();
thr.start();
try {
thr.join();
} catch (InterruptedException e) {
assertTrue(false);
}
}
}
public void func() {
new Runnable() {
@Override
public void run() {
count += 4;
}
}.run();
}
public static class MyException extends Exception {
public MyException(String str, Exception e) {
super("msg:" + str, e);
}
}
@Override
public boolean testRun() throws Exception {
TestInner c = new TestInner();
TestInner.count = 0;
c.func();
Runnable myRunnable = new Runnable() {
@Override
public void run() {
TestInner.count += 8;
}
};
myRunnable.run();
MyThread thread = new TestInner.MyThread("my thread");
thread.start();
MyInceptionThread thread2 = new TestInner.MyInceptionThread();
thread2.start();
thread.join();
thread2.join();
return TestInner.count == 15;
}
}
@@ -0,0 +1,87 @@
package jadx.samples;
import java.lang.reflect.Method;
public class TestInner2 extends AbstractTest {
private String a;
public class A {
public A() {
a = "a";
}
public String a() {
return a;
}
}
private static String b;
public static class B {
public B() {
b = "b";
}
public String b() {
return b;
}
}
private String c;
private void setC(String c) {
this.c = c;
}
public class C {
public String c() {
setC("c");
return c;
}
}
private static String d;
private static void setD(String s) {
d = s;
}
public static class D {
public String d() {
setD("d");
return d;
}
}
// value from java.lang.reflect.Modifier
static final int SYNTHETIC = 0x00001000;
@Override
public boolean testRun() throws Exception {
assertTrue((new A()).a().equals("a"));
assertTrue(a.equals("a"));
assertTrue((new B()).b().equals("b"));
assertTrue(b.equals("b"));
assertTrue((new C()).c().equals("c"));
assertTrue(c.equals("c"));
assertTrue((new D()).d().equals("d"));
assertTrue(d.equals("d"));
Method[] mths = TestInner2.class.getDeclaredMethods();
for (Method mth : mths) {
if(mth.getName().startsWith("access$")) {
int modifiers = mth.getModifiers();
assertTrue((modifiers & SYNTHETIC) != 0, "Synthetic methods must be removed");
}
}
return true;
}
public static void main(String[] args) throws Exception {
new TestInner2().testRun();
}
}
@@ -0,0 +1,68 @@
package jadx.samples;
import java.util.Arrays;
public class TestInvoke extends AbstractTest {
private int f;
public TestInvoke() {
this(-1);
}
public TestInvoke(int f) {
this.f = f;
}
private void parse(String[] args) {
if (args.length > 0)
f = Integer.parseInt(args[0]);
else
f = 20;
}
public int getF() {
return f;
}
private boolean testVarArgs(String s1, String... args) {
String str = Arrays.toString(args);
return s1.length() + str.length() > 0;
}
private String testVarArgs2(char[]... args) {
String s = "";
for (char[] ca : args) {
s += new String(ca);
}
return s;
}
/* TODO
public TestInvoke testConstructor(int flag) {
if (getF() == flag)
return new TestInvoke(flag);
else
return this;
}
*/
@Override
public boolean testRun() throws Exception {
TestInvoke inv = new TestInvoke();
inv.parse(new String[] { "12", "35" });
assertTrue(inv.getF() == 12);
inv.parse(new String[0]);
assertTrue(inv.getF() == 20);
assertTrue(inv.testVarArgs("a", "2", "III"));
assertTrue(inv.testVarArgs2("a".toCharArray(), new char[] { '1', '2' }).equals("a12"));
// assertTrue(testConstructor(f) != this);
return true;
}
public static void main(String[] args) throws Exception {
new TestInvoke().testRun();
}
}
@@ -0,0 +1,24 @@
package jadx.samples;
public class TestStringProcessing extends AbstractTest {
public void testStringEscape() {
String str = "test\tstr\n";
assertTrue(str.length() == 9);
str = "test\bunicode\u1234";
assertTrue(str.charAt(4) == '\b');
}
public void testStringConcat() {
String s = "1";
assertEquals("a" + s, "a1");
}
@Override
public boolean testRun() throws Exception {
testStringEscape();
testStringConcat();
return true;
}
}
@@ -0,0 +1,120 @@
package jadx.samples;
public class TestSwitch extends AbstractTest {
public static final int test1(int i) {
int k = i * 4;
switch (k) {
case 1:
return 0;
case 10:
return 1;
case 100:
return 2;
case 1000:
return 3;
}
i -= 77;
return i;
}
public static final int test2(int i) {
int k = i;
switch (k) {
case 1:
return 0;
case 2:
return 1;
case 3:
return 2;
case 5:
return 3;
case 7:
return 4;
case 9:
return 5;
}
i /= 2;
return -i;
}
public static final int test3(int i, int j) {
int k = i;
switch (k) {
case 1:
if (j == 0)
return 0;
else
return -1;
case 2:
return 1;
}
return -1;
}
public static final int test4(int i) {
int k = i;
switch (k) {
case 1:
throw new RuntimeException("test4");
case 2:
return 1;
}
return -1;
}
public static final int test5(int i, int b) {
int k = i;
switch (k) {
case 1:
if (b == 0)
return 3;
case 2:
b++;
return b;
}
return -1;
}
public String escape(String str) {
int len = str.length();
StringBuilder sb = new StringBuilder(len);
for (int i = 0; i < len; i++) {
char c = str.charAt(i);
switch (c) {
case '.':
case '/':
sb.append('_');
break;
case ']':
sb.append('A');
break;
case '?':
break;
default:
sb.append(c);
break;
}
}
return sb.toString();
}
@Override
public boolean testRun() {
assertTrue(test1(25) == 2);
assertTrue(test2(5) == 3);
assertTrue(test3(1, 0) == 0);
assertTrue(test4(2) == 1);
assertEquals(escape("a.b/c]d?e"), "a_b_cAde");
return true;
}
public static void main(String[] args) {
new TestSwitch().testRun();
}
}
@@ -0,0 +1,200 @@
package jadx.samples;
import java.io.IOException;
public class TestTryCatch extends AbstractTest {
private static boolean exc(Object obj) throws Exception {
if (obj == null)
throw new Exception("test");
return (obj instanceof Object);
}
private static boolean exc2(Object obj) throws IOException {
if (obj == null)
throw new IOException();
return true;
}
private static boolean test0(Object obj) {
try {
synchronized (obj) {
obj.wait(5);
}
} catch (InterruptedException e) {
return false;
}
return true;
}
private static boolean test1(Object obj) {
boolean res = false;
try {
res = exc(obj);
} catch (Exception e) {
return false;
}
return res;
}
private static boolean test2(Object obj) {
try {
return exc(obj);
} catch (Exception e) {
if (obj != null)
return true;
else
return false;
}
}
private static boolean test3(Object obj) {
boolean res = false;
try {
res = exc(obj);
} catch (Exception e) {
res = false;
} finally {
test0(obj);
}
return res;
}
private static String test4(Object obj) {
String res = "good";
try {
res += exc(obj);
exc2("a");
} catch (IOException e) {
res = "io exc";
} catch (Exception e) {
res = "exc";
}
return res;
}
private static String test5(Object obj) {
String res = "good";
try {
res = "" + exc(obj);
boolean f = exc2("a");
if (!f)
res = "f == false";
} catch (Exception e) {
res = "exc";
}
return res;
}
private static boolean test6(Object obj) {
boolean res = false;
while (true) {
try {
res = exc2(obj);
return res;
} catch (IOException e) {
res = true;
} catch (Throwable e) {
if (obj == null)
obj = new Object();
}
}
}
private static boolean test7() {
boolean res = false;
Object obj = null;
while (true) {
try {
res = exc2(obj);
return res;
} catch (IOException e) {
res = true;
obj = new Object();
} catch (Throwable e) {
if (obj == null)
res = false;
}
}
}
private boolean test8(Object obj) {
this.mDiscovering = false;
try {
exc(obj);
} catch (Exception e) {
e.toString();
} finally {
mDiscovering = true;
}
return mDiscovering;
}
private boolean test8a(Object obj) {
this.mDiscovering = false;
try {
exc(obj);
} catch (Exception e) {
e.toString();
} finally {
if (!mDiscovering)
mDiscovering = true;
}
return mDiscovering;
}
private static boolean testSynchronize(Object obj) throws InterruptedException {
synchronized (obj) {
if (obj instanceof String)
return false;
obj.wait(5);
}
return true;
}
// TODO: remove 'synchronized(TestTryCatch.class)' block in decompiled version
private synchronized static boolean testSynchronize2(Object obj) throws InterruptedException {
return obj.toString() != null;
}
public Object mObject = new Object();
public boolean mDiscovering = true;
private boolean testSynchronize3() {
boolean b = false;
synchronized (mObject) {
b = this.mDiscovering;
}
return b;
}
@Override
public boolean testRun() throws Exception {
Object obj = new Object();
assertTrue(test0(obj));
assertTrue(test1(obj));
assertTrue(test2(obj));
assertTrue(test3(obj));
assertTrue(test4(obj) != null);
assertTrue(test5(null) != null);
assertTrue(test6(obj));
assertTrue(test7());
assertTrue(testSynchronize(obj) == true);
assertTrue(testSynchronize("str") == false);
assertTrue(testSynchronize2("str"));
assertTrue(testSynchronize3());
assertTrue(test8("a"));
assertTrue(test8(null));
assertTrue(test8a("a"));
assertTrue(test8a(null));
return true;
}
public static void main(String[] args) throws Exception {
new TestTryCatch().testRun();
}
}
@@ -0,0 +1,54 @@
package jadx.samples;
public class TestTypeResolver extends AbstractTest {
private final int f1;
public TestTypeResolver() {
this.f1 = 2;
}
public TestTypeResolver(int b1, int b2) {
// test 'this' move and constructor invocation on moved register
this(b1, b2, 0, 0, 0);
}
public TestTypeResolver(int a1, int a2, int a3, int a4, int a5) {
this.f1 = a1;
}
public static class TestTernaryInSuper extends TestTypeResolver {
public TestTernaryInSuper(int c) {
super(c > 0 ? c : -c, 1);
}
}
// public static Object testVarsPropagation(int a) {
// Object b = new Exception();
// if (a == 5)
// b = 1;
// return b;
// }
//
// public Object testMoveThis(int a) {
// TestTypeResolver t = this;
// if (a == 0)
// return t;
//
// return t.testMoveThis(--a);
// }
@Override
public boolean testRun() throws Exception {
// assertTrue((Integer) testVarsPropagation(5) == 1);
// assertTrue(testVarsPropagation(1).getClass() == Exception.class);
//
// assertTrue(testMoveThis(f1) == this);
return true;
}
public static void main(String[] args) throws Exception {
new TestTypeResolver().testRun();
}
}