Skip to content
Permalink
Browse files

Fix lexing regression in certain types of method parameter lists

It was mis-lexing the case when a class descriptor is immediately
followed by a primitive type. The primitive type was being lexed as
PARAM_LIST_OR_ID_PRIMITIVE_TYPE instead of PRIMITIVE_TYPE.

The root cause was due to an incorrect state change. Since the
CLASS_DESCRIPTOR state can be started from within the PARAM_LIST state,
but when the CLASS_DESCRIPTOR state ends it just went back to YYINITIAL,
instead of going back to PARAM_LIST.

This adds a state stack to track these state changes
  • Loading branch information...
JesusFreke committed Sep 19, 2019
1 parent 2598dff commit ae2efe146b8c571821365ec7d43e6db070a678d9
@@ -1,6 +1,7 @@
package org.jf.smali;

import java.io.*;
import java.util.Stack;
import org.antlr.runtime.*;
import org.jf.smali.util.*;
import org.jf.util.*;
@@ -38,6 +39,8 @@ import static org.jf.smali.smaliParser.*;

private int apiLevel;

private Stack<Integer> stateStack = new Stack<>();

public Token nextToken() {
try {
Token token = yylex();
@@ -137,6 +140,7 @@ import static org.jf.smali.smaliParser.*;
}

private void beginStateBasedToken(int state) {
stateStack.push(yystate());
yybegin(state);
sb.setLength(0);
tokenStartLine = getLine();
@@ -146,12 +150,12 @@ import static org.jf.smali.smaliParser.*;
}

private Token endStateBasedToken(int type) {
yybegin(YYINITIAL);

if (tokenError != null) {
return invalidStateBasedToken(tokenError);
}

yybegin(stateStack.pop());

CommonToken token = new CommonToken(type, sb.toString());
token.setStartIndex(tokenStartChar);
token.setStopIndex(yychar + yylength() - 1);
@@ -167,7 +171,7 @@ import static org.jf.smali.smaliParser.*;
}

private Token invalidStateBasedToken(String message) {
yybegin(YYINITIAL);
yybegin(stateStack.pop());

InvalidToken token = new InvalidToken(message, sb.toString());
token.setStartIndex(tokenStartChar);
@@ -734,7 +738,6 @@ Type = {PrimitiveType} | {ClassDescriptor} | {ArrayPrefix} ({ClassDescriptor} |
{ClassDescriptor} {
yypushback(yylength());
beginStateBasedToken(CLASS_DESCRIPTOR_BEGINNING);
sb.append(yytext());
}

// we have to drop into a separate state so that we don't parse something like
@@ -37,6 +37,7 @@ IIIII
ZBSCIJFD
ILa;[La;[I
Ljava/lang/String;Ljava/lang/String;
IIFFIILjava/lang/String;IIFFII
[I[I[I
[I[Z
[I[Ljava/lang/String;
@@ -73,6 +73,20 @@ PRIMITIVE_TYPE("I")
CLASS_DESCRIPTOR("Ljava/lang/String;")
CLASS_DESCRIPTOR("Ljava/lang/String;")

PRIMITIVE_TYPE("I")
PRIMITIVE_TYPE("I")
PRIMITIVE_TYPE("F")
PRIMITIVE_TYPE("F")
PRIMITIVE_TYPE("I")
PRIMITIVE_TYPE("I")
CLASS_DESCRIPTOR("Ljava/lang/String;")
PRIMITIVE_TYPE("I")
PRIMITIVE_TYPE("I")
PRIMITIVE_TYPE("F")
PRIMITIVE_TYPE("F")
PRIMITIVE_TYPE("I")
PRIMITIVE_TYPE("I")

ARRAY_TYPE_PREFIX("[")
PRIMITIVE_TYPE("I")
ARRAY_TYPE_PREFIX("[")
@@ -37,6 +37,7 @@ IIIII
ZBSCIJFD
ILa;[La;[I
Ljava/lang/String;Ljava/lang/String;
IIFFIILjava/lang/String;IIFFII
[I[I[I
[I[Z
[I[Ljava/lang/String;
@@ -73,6 +73,20 @@ PRIMITIVE_TYPE("I")
CLASS_DESCRIPTOR("Ljava/lang/String;")
CLASS_DESCRIPTOR("Ljava/lang/String;")

PRIMITIVE_TYPE("I")
PRIMITIVE_TYPE("I")
PRIMITIVE_TYPE("F")
PRIMITIVE_TYPE("F")
PRIMITIVE_TYPE("I")
PRIMITIVE_TYPE("I")
CLASS_DESCRIPTOR("Ljava/lang/String;")
PRIMITIVE_TYPE("I")
PRIMITIVE_TYPE("I")
PRIMITIVE_TYPE("F")
PRIMITIVE_TYPE("F")
PRIMITIVE_TYPE("I")
PRIMITIVE_TYPE("I")

ARRAY_TYPE_PREFIX("[")
PRIMITIVE_TYPE("I")
ARRAY_TYPE_PREFIX("[")

0 comments on commit ae2efe1

Please sign in to comment.
You can’t perform that action at this time.