Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

InvokeArgumentValidator changes #865

Draft
wants to merge 13 commits into
base: develop
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -22,31 +22,42 @@
* #L%
*/

import java.util.List;
import sootup.core.jimple.common.expr.AbstractInvokeExpr;
import sootup.core.jimple.common.stmt.Stmt;
import sootup.core.model.Body;
import sootup.core.signatures.MethodSignature;
import sootup.core.views.View;

import java.util.ArrayList;
import java.util.List;

/**
* A basic validator that checks whether the length of the invoke statement's argument list matches
* the length of the target methods's parameter type list.
*
* @author Steven Arzt
*/
public class InvokeArgumentValidator implements BodyValidator {
@Override
public List<ValidationException> validate(Body body, View view) {
List<ValidationException> validationException = new ArrayList<>();

@Override
public List<ValidationException> validate(Body body, View view) {
// TODO: check copied code from old soot
/*
* for (Unit u : body.getUnits()) { Stmt s = (Stmt) u; if (s.containsInvokeExpr()) { InvokeExpr iinvExpr =
* s.getInvokeExpr(); SootMethod callee = iinvExpr.getMethod(); if (callee != null && iinvExpr.getArgCount() !=
* callee.getParameterCount()) { exceptions.add(new ValidationException(s, "Invalid number of arguments")); } } }
*/
return null;
}
for (Stmt stmt : body.getStmts()) {
if (stmt.containsInvokeExpr()) {
AbstractInvokeExpr invExpr =
stmt.getInvokeExpr();
MethodSignature callee = invExpr.getMethodSignature();
if (invExpr.getArgCount() !=
callee.getParameterTypes().size()) {
Momo-Not-Emo marked this conversation as resolved.
Show resolved Hide resolved
validationException.add(new ValidationException(stmt, "Invalid number of arguments"));
}
}
Momo-Not-Emo marked this conversation as resolved.
Show resolved Hide resolved
}
return validationException;
}

@Override
public boolean isBasicValidator() {
return true;
}
@Override
public boolean isBasicValidator() {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

import sootup.core.jimple.basic.Local;
import sootup.core.jimple.basic.Value;
import sootup.core.jimple.common.stmt.Stmt;
import sootup.core.model.SootClass;
import sootup.core.model.SootMethod;

Expand Down Expand Up @@ -58,4 +59,8 @@ public ValidationException(SootMethod method, String s, String s1) {
// TODO: auto generated stub

}

public ValidationException(Stmt stmt, String s) {
// TODO: auto generated stub
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package sootup.tests.validator;

import org.junit.Before;
import org.junit.Test;
import sootup.core.model.SootClass;
import sootup.core.model.SourceType;
import sootup.core.signatures.PackageName;
import sootup.core.types.ClassType;
import sootup.core.validation.InvokeArgumentValidator;
import sootup.core.validation.ValidationException;
import sootup.jimple.parser.JimpleAnalysisInputLocation;
import sootup.jimple.parser.JimpleView;

import java.nio.file.Paths;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;

public class InvokeArgumentValidatorTest {
InvokeArgumentValidator invokeArgumentValidator;
JimpleView jimpleView;
Collection<SootClass> classes;

@Before
public void Setup() {

invokeArgumentValidator = new InvokeArgumentValidator();

ClassType classTypeFieldRefValidator =
new ClassType() {
@Override
public boolean isBuiltInClass() {
return false;
}

@Override
public String getFullyQualifiedName() {
return "jimple.InvokeArgumentValidator";
}

@Override
public String getClassName() {
return "InvokeArgumentValidator";
}

@Override
public PackageName getPackageName() {
return new PackageName("jimple");
}
};

String classPath = "src/test/resources/validator/jimple";
JimpleAnalysisInputLocation jimpleInputLocation =
new JimpleAnalysisInputLocation(Paths.get(classPath), SourceType.Application);

jimpleView = new JimpleView(jimpleInputLocation);
final Optional<SootClass> classSource1 = jimpleView.getClass(classTypeFieldRefValidator);
assertFalse(classSource1.isPresent());

classes = new HashSet<>(); // Set to track the classes to check

for (SootClass aClass : jimpleView.getClasses()) {
if (!aClass.isLibraryClass()) {
Momo-Not-Emo marked this conversation as resolved.
Show resolved Hide resolved
classes.add(aClass);
}
}
}

@Test
public void testInvokeArgumentValidatorSuccess() {
List<ValidationException> validationExceptions_success;

validationExceptions_success =
invokeArgumentValidator.validate(
classes.stream()
.filter(c -> c.getType().getClassName().equals("InvokeArgumentValidator"))
.findFirst()
.get()
.getMethods()
.stream()
.filter(m -> m.getName().equals("invokeArgumentValidator_success"))
.map(m -> m.getBody())
.findFirst()
.get(),
Momo-Not-Emo marked this conversation as resolved.
Show resolved Hide resolved
jimpleView);

assertEquals(0, validationExceptions_success.size());
}

@Test
public void testInvokeArgumentValidatorFailure() {
List<ValidationException> validationExceptions_success;

validationExceptions_success =
invokeArgumentValidator.validate(
classes.stream()
.filter(c -> c.getType().getClassName().equals("InvokeArgumentValidator"))
.findFirst()
.get()
.getMethods()
.stream()
.filter(m -> m.getName().equals("invokeArgumentValidator_fail"))
.map(m -> m.getBody())
.findFirst()
.get(),
jimpleView);
assertEquals(1, validationExceptions_success.size());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
public class InvokeArgumentValidator extends java.lang.Object
{
public void <init>()
{
InvokeArgumentValidator l0;

l0 := @this: InvokeArgumentValidator;
specialinvoke l0.<java.lang.Object: void <init>()>();

return;
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add a testcase for array types. Primitive type array, Classtype array and both cases also as multi-dimensional array

public java.lang.String join(int,java.lang.String)
{
InvokeArgumentValidator l0;
int l1;
java.lang.String l2;
unknown $stack3;


l0 := @this: InvokeArgumentValidator;
l1 := @parameter0: int;
l2 := @parameter1: java.lang.String;
$stack3 = dynamicinvoke "makeConcatWithConstants" <java.lang.String (int,java.lang.String)>(l1, l2) <java.lang.invoke.StringConcatFactory: java.lang.invoke.CallSite makeConcatWithConstants(java.lang.invoke.MethodHandles$Lookup,java.lang.String,java.lang.invoke.MethodType,java.lang.String,java.lang.Object[])>("\u0001\u0001");

return $stack3;
}

public void invokeArgumentValidator_success()
{
InvokeArgumentValidator l0;
unknown l1;


l0 := @this: InvokeArgumentValidator;
l1 = virtualinvoke l0.<InvokeArgumentValidator: java.lang.String join(int,java.lang.String)>(1, "hello world");

return;
}

public void invokeArgumentValidator_fail()
{
InvokeArgumentValidator l0;
unknown l1;


l0 := @this: InvokeArgumentValidator;
l1 = virtualinvoke l0.<InvokeArgumentValidator: java.lang.String join(int,java.lang.String)>(1);

return;
}
}