提交 009939f8 编写于 作者: S Skylot

fix: prevent endless loop in method signature parsing (#1007)

Signed-off-by: NSkylot <skylot@gmail.com>
上级 cd006ce7
......@@ -151,6 +151,9 @@ public class SignatureParser {
String typeVarName = consumeUntil(';');
if (typeVarName != null) {
consume(';');
if (typeVarName.contains(")")) {
throw new JadxRuntimeException("Bad name for type variable: " + typeVarName);
}
return ArgType.genericType(typeVarName);
}
break;
......@@ -268,8 +271,7 @@ public class SignatureParser {
}
String id = consumeUntil(':');
if (id == null) {
LOG.error("Failed to parse generic types map: {}", sign);
return Collections.emptyList();
throw new JadxRuntimeException("Failed to parse generic types map");
}
consume(':');
tryConsume(':');
......@@ -290,9 +292,12 @@ public class SignatureParser {
boolean next;
do {
ArgType argType = consumeType();
if (argType == null) {
throw new JadxRuntimeException("Unexpected end of signature");
}
if (!argType.equals(ArgType.OBJECT)) {
if (types.isEmpty()) {
types = new LinkedList<>();
types = new ArrayList<>();
}
types.add(argType);
}
......@@ -304,15 +309,23 @@ public class SignatureParser {
return types;
}
public List<ArgType> consumeMethodArgs() {
public List<ArgType> consumeMethodArgs(int argsCount) {
consume('(');
if (lookAhead(')')) {
consume(')');
return Collections.emptyList();
}
List<ArgType> args = new LinkedList<>();
List<ArgType> args = new ArrayList<>(argsCount);
int limit = argsCount + 10; // just prevent endless loop, args count can be different for synthetic methods
do {
args.add(consumeType());
ArgType type = consumeType();
if (type == null) {
throw new JadxRuntimeException("Unexpected end of signature");
}
args.add(type);
if (args.size() > limit) {
throw new JadxRuntimeException("Arguments count limit reached: " + args.size());
}
} while (!lookAhead(')'));
consume(')');
return args;
......
......@@ -103,7 +103,7 @@ public class SignatureProcessor extends AbstractVisitor {
}
try {
List<ArgType> typeParameters = sp.consumeGenericTypeParameters();
List<ArgType> parsedArgTypes = sp.consumeMethodArgs();
List<ArgType> parsedArgTypes = sp.consumeMethodArgs(mth.getMethodInfo().getArgsCount());
ArgType parsedRetType = sp.consumeType();
if (!validateParsedType(parsedRetType, mth.getMethodInfo().getReturnType())) {
......
......@@ -8,6 +8,7 @@ import org.junit.jupiter.api.Test;
import jadx.core.dex.instructions.args.ArgType;
import jadx.core.dex.instructions.args.ArgType.WildcardBound;
import jadx.core.dex.nodes.parser.SignatureParser;
import jadx.core.utils.exceptions.JadxRuntimeException;
import static jadx.core.dex.instructions.args.ArgType.INT;
import static jadx.core.dex.instructions.args.ArgType.OBJECT;
......@@ -19,6 +20,7 @@ import static jadx.core.dex.instructions.args.ArgType.outerGeneric;
import static jadx.core.dex.instructions.args.ArgType.wildcard;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
......@@ -114,7 +116,7 @@ class SignatureParserTest {
@Test
public void testMethodArgs() {
List<ArgType> argTypes = new SignatureParser("(Ljava/util/List<*>;)V").consumeMethodArgs();
List<ArgType> argTypes = new SignatureParser("(Ljava/util/List<*>;)V").consumeMethodArgs(1);
assertThat(argTypes, hasSize(1));
assertThat(argTypes.get(0), is(generic("Ljava/util/List;", wildcard())));
......@@ -122,7 +124,7 @@ class SignatureParserTest {
@Test
public void testMethodArgs2() {
List<ArgType> argTypes = new SignatureParser("(La/b/C<TT;>.d/E;)V").consumeMethodArgs();
List<ArgType> argTypes = new SignatureParser("(La/b/C<TT;>.d/E;)V").consumeMethodArgs(1);
assertThat(argTypes, hasSize(1));
ArgType argType = argTypes.get(0);
......@@ -132,7 +134,13 @@ class SignatureParserTest {
@Test
public void testBadGenericMap() {
List<ArgType> list = new SignatureParser("<A:Ljava/lang/Object;B").consumeGenericTypeParameters();
assertThat(list, hasSize(0));
assertThatExceptionOfType(JadxRuntimeException.class)
.isThrownBy(() -> new SignatureParser("<A:Ljava/lang/Object;B").consumeGenericTypeParameters());
}
@Test
public void testBadArgs() {
assertThatExceptionOfType(JadxRuntimeException.class)
.isThrownBy(() -> new SignatureParser("(TCONTENT)Lpkg/Cls;").consumeMethodArgs(1));
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册