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

NewValidator Changes #733

Merged
merged 29 commits into from
Jan 2, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
1fb79eb
Refactored NewValidator.java to work with Sootup.
akshitad11 Oct 30, 2023
dc0277b
Changes in NewValidator.java
akshitad11 Oct 30, 2023
be5face
Formatting changes after executing fmt maven plugin.
akshitad11 Nov 2, 2023
bbf8513
add Validator Interceptor draft
swissiety Nov 10, 2023
81034eb
add licenseheader
swissiety Nov 11, 2023
32d3e8d
Changes to increase test coverage.
akshitad11 Nov 15, 2023
242492f
Merge branch 'develop' of https://github.com/soot-oss/SootUp into val…
akshitad11 Nov 15, 2023
4961fe2
Formatting changes
akshitad11 Nov 16, 2023
4d3022c
minor
kadirayk Nov 22, 2023
9722c61
Merge branch 'develop' of https://github.com/soot-oss/SootUp into val…
akshitad11 Nov 30, 2023
6868bb4
validate method signature change
akshitad11 Dec 6, 2023
2368035
Merge branch 'develop' of https://github.com/soot-oss/SootUp into val…
akshitad11 Dec 6, 2023
30bde64
Deleting files, jimple file used for testing
akshitad11 Dec 6, 2023
e7eae50
Renaming to handle ambiguity
akshitad11 Dec 11, 2023
3e99c3a
Merge branch 'develop' of https://github.com/soot-oss/SootUp into val…
akshitad11 Dec 11, 2023
d8e357a
use equals instead of contains
kadirayk Dec 19, 2023
8085ac9
move test to integration
kadirayk Dec 19, 2023
7d21bf9
Merge remote-tracking branch 'origin/develop' into validator_changes
kadirayk Dec 19, 2023
732bcd3
remove JimpleProject
kadirayk Dec 19, 2023
8bde134
remove hardcoded version
kadirayk Dec 19, 2023
331d059
Fixing Tests
akshitad11 Dec 19, 2023
dba836e
Merge remote-tracking branch 'origin/validator_changes' into validato…
akshitad11 Dec 19, 2023
397dcef
Merge branch 'develop' into validator_changes
akshitad11 Dec 19, 2023
3bcdb99
Refactoring NewValidator tests
akshitad11 Dec 19, 2023
64f5d8d
Commenting FieldRefValidator changes.
akshitad11 Dec 20, 2023
57209fb
Rollback changes for FieldRefValidator
akshitad11 Dec 21, 2023
e2a0747
Rollback changes for FieldRefValidator
akshitad11 Dec 21, 2023
ae8ede5
Rollback LocalsValidator changes
akshitad11 Dec 21, 2023
3dd6d09
Formatting changes
akshitad11 Dec 25, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
public class NewKeywordValidator {
kadirayk marked this conversation as resolved.
Show resolved Hide resolved

int x = 5;

public static void main(String[] args) {
NewKeywordValidator myObj = new NewKeywordValidator();
System.out.println(myObj.x);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import sootup.core.model.Body;
import sootup.core.model.Position;
import sootup.core.types.Type;
import sootup.core.types.VoidType;
import sootup.core.util.Copyable;
import sootup.core.util.printer.StmtPrinter;

Expand All @@ -57,7 +58,11 @@
/** Constructs a JimpleLocal of the given name and type. */
public Local(@Nonnull String name, @Nonnull Type type, @Nonnull Position position) {
this.name = name;
this.type = type;
if (type instanceof VoidType) {
throw new RuntimeException("Type should not be VoidType");

Check warning on line 62 in sootup.core/src/main/java/sootup/core/jimple/basic/Local.java

View check run for this annotation

Codecov / codecov/patch

sootup.core/src/main/java/sootup/core/jimple/basic/Local.java#L62

Added line #L62 was not covered by tests
} else {
this.type = type;
}
this.position = position;
}

Expand Down
3 changes: 1 addition & 2 deletions sootup.core/src/main/java/sootup/core/model/Body.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,7 @@ public class Body implements Copyable {
new ValuesValidator(),
new CheckInitValidator(),
new CheckTypesValidator(),
new CheckVoidLocalesValidator(),
new CheckEscapingValidator());
new CheckVoidLocalesValidator());

/**
* Creates an body which is not associated to any method.
Expand Down

This file was deleted.

238 changes: 138 additions & 100 deletions sootup.core/src/main/java/sootup/core/validation/NewValidator.java
Original file line number Diff line number Diff line change
@@ -1,116 +1,154 @@
package sootup.core.validation;

/*-
* #%L
* Soot - a J*va Optimization Framework
* %%
* Copyright (C) 1997-2020 Raja Vallée-Rai, Christian Brüggemann, Markus Schmidt and others
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 2.1 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/lgpl-2.1.html>.
* #L%
*/

import java.util.List;
import java.util.*;
Copy link
Member

Choose a reason for hiding this comment

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

we need the license headers, you can add your name too.

import sootup.core.graph.StmtGraph;
import sootup.core.jimple.basic.Local;
import sootup.core.jimple.basic.Value;
import sootup.core.jimple.common.expr.AbstractInvokeExpr;
import sootup.core.jimple.common.expr.JNewExpr;
import sootup.core.jimple.common.expr.JSpecialInvokeExpr;
import sootup.core.jimple.common.stmt.JAssignStmt;
import sootup.core.jimple.common.stmt.JInvokeStmt;
import sootup.core.jimple.common.stmt.Stmt;
import sootup.core.model.Body;
import sootup.core.types.ReferenceType;
import sootup.core.types.UnknownType;

/**
* A relatively simple validator. It tries to check whether after each new-expression-statement
* there is a corresponding call to the &lt;init&gt; method before a use or the end of the method.
*
* @author Marc Miltenberger
* @author Steven Arzt
*/
public class NewValidator implements BodyValidator {

private static final String errorMsg =
"There is a path from '%s' to the usage '%s' where <init> does not get called in between.";

public static boolean MUST_CALL_CONSTRUCTOR_BEFORE_RETURN = false;

/** Checks whether after each new-instruction a constructor call follows. */
// Checks whether after each new-instruction a constructor call follows.
@Override
public void validate(Body body, List<ValidationException> exceptions) {
// TODO: check copied code from old soot
/*
* UnitGraph g = new BriefUnitGraph(body); for (Unit u : body.getUnits()) { if (u instanceof JAssignStmt) { JAssignStmt
* assign = (JAssignStmt) u;
*
* // First seek for a JNewExpr. if (assign.getRightOp() instanceof JNewExpr) { if (!(assign.getLeftOp().getType()
* instanceof RefType)) { exceptions.add(new ValidationException(u,
* "A new-expression must be used on reference type locals",
* String.format("Body of methodRef %s contains a new-expression, which is assigned to a non-reference local",
* body.getMethod().getSignature()))); return; }
*
* // We search for a JSpecialInvokeExpr on the local. LinkedHashSet<Local> locals = new LinkedHashSet<Local>();
* locals.add((Local) assign.getLeftOp());
*
* checkForInitializerOnPath(g, assign, exceptions); } } }
*
* }
*
*
* <p> Checks whether all pathes from start to the end of the methodRef have a call to the &lt;init&gt; methodRef in
* between. </p> <code> $r0 = new X;<br> ...<br> specialinvoke $r0.<X: void <init>()>; //validator checks whether this
* statement is missing </code> <p> Regarding <i>aliasingLocals</i>:<br> The first local in the set is always the local
* on the LHS of the new-expression-assignment (called: original local; in the example <code>$r0</code>). </p>
*
* @param g the unit graph of the methodRef
*
* @param exception the list of all collected exceptions
*
* @return true if a call to a &lt;init&gt;-Method has been found on this way.
*
* private boolean checkForInitializerOnPath(UnitGraph g, AssignStmt newStmt, List<ValidationException> exception) {
* List<Unit> workList = new ArrayList<Unit>(); Set<Unit> doneSet = new HashSet<Unit>(); workList.add(newStmt);
*
* Set<Local> aliasingLocals = new HashSet<Local>(); aliasingLocals.add((Local) newStmt.getLeftOp());
*
* while (!workList.isEmpty()) { Stmt curStmt = (Stmt) workList.remove(0); if (!doneSet.add(curStmt)) { continue; } if
* (!newStmt.equals(curStmt)) { if (curStmt.containsInvokeExpr()) { InvokeExpr expr = curStmt.getInvokeExpr(); if
* (expr.getMethod().isConstructor()) { if (!(expr instanceof SpecialInvokeExpr)) { exception.add(new
* ValidationException(curStmt, "<init> methodRef calls may only be used with specialinvoke.")); // At least we found an
* initializer, so we return true... return true; } if (!(curStmt instanceof InvokeStmt)) { exception.add(new
* ValidationException(curStmt, "<init> methods may only be called with invoke statements.")); // At least we found an
* initializer, so we return true... return true; }
*
* SpecialInvokeExpr invoke = (SpecialInvokeExpr) expr; if (aliasingLocals.contains(invoke.getBase())) { // We are happy
* now, continue the loop and check other paths continue; } } }
*
* // We are still in the loop, so this was not the constructor call we // were looking for boolean creatingAlias =
* false; if (curStmt instanceof AssignStmt) { AssignStmt assignCheck = (AssignStmt) curStmt; if
* (aliasingLocals.contains(assignCheck.getRightOp())) { if (assignCheck.getLeftOp() instanceof Local) { // A new alias
* is created. aliasingLocals.add((Local) assignCheck.getLeftOp()); creatingAlias = true; } } Local originalLocal =
* aliasingLocals.iterator().next(); if (originalLocal.equals(assignCheck.getLeftOp())) { // In case of dead assignments:
*
* // Handles cases like // $r0 = new x; // $r0 = null;
*
* // But not cases like // $r0 = new x; // $r1 = $r0; // $r1 = null; // Because we check for the original local
* continue; } else { // Since the local on the left hand side gets overwritten // even if it was aliasing with our
* original local, // now it does not any more... aliasingLocals.remove(assignCheck.getLeftOp()); } }
*
* if (!creatingAlias) { for (ValueBox box : curStmt.getUseBoxes()) { Value used = box.getValue(); if
* (aliasingLocals.contains(used)) { // The current unit uses one of the aliasing locals, but // there was no initializer
* in between. // However, when creating such an alias, the use is okay. exception.add(new ValidationException(newStmt,
* String.format(errorMsg, newStmt, curStmt))); return false; } } } } // Enqueue the successors List<Unit> successors =
* g.getSuccsOf(curStmt); if (successors.isEmpty() && MUST_CALL_CONSTRUCTOR_BEFORE_RETURN) { // This means that we are
* e.g. at the end of the methodRef // There was no <init> call on our way... exception.add(new
* ValidationException(newStmt, String.format(errorMsg, newStmt, curStmt))); return false; } workList.addAll(successors);
* } return true;
*
*
*/

StmtGraph g = body.getStmtGraph();
for (Stmt u : body.getStmts()) {
if (u instanceof JAssignStmt) {
JAssignStmt assign = (JAssignStmt) u;

// First seek for a JNewExpr.
if (assign.getRightOp() instanceof JNewExpr) {
if (!((assign.getLeftOp().getType() instanceof ReferenceType)
|| assign.getLeftOp().getType() instanceof UnknownType)) {
exceptions.add(

Check warning on line 37 in sootup.core/src/main/java/sootup/core/validation/NewValidator.java

View check run for this annotation

Codecov / codecov/patch

sootup.core/src/main/java/sootup/core/validation/NewValidator.java#L37

Added line #L37 was not covered by tests
new ValidationException(
assign.getLeftOp(),
String.format(

Check warning on line 40 in sootup.core/src/main/java/sootup/core/validation/NewValidator.java

View check run for this annotation

Codecov / codecov/patch

sootup.core/src/main/java/sootup/core/validation/NewValidator.java#L39-L40

Added lines #L39 - L40 were not covered by tests
"Body of methodRef %s contains a new-expression, which is assigned to a non-reference local",
body.getMethodSignature())));
return;

Check warning on line 43 in sootup.core/src/main/java/sootup/core/validation/NewValidator.java

View check run for this annotation

Codecov / codecov/patch

sootup.core/src/main/java/sootup/core/validation/NewValidator.java#L42-L43

Added lines #L42 - L43 were not covered by tests
}

// We search for a JSpecialInvokeExpr on the local.
LinkedHashSet<Local> locals = new LinkedHashSet<Local>();
locals.add((Local) assign.getLeftOp());
kadirayk marked this conversation as resolved.
Show resolved Hide resolved

checkForInitializerOnPath(g, assign, exceptions);
}
}
}
}

private boolean checkForInitializerOnPath(
StmtGraph g, JAssignStmt newStmt, List<ValidationException> exception) {
List<Stmt> workList = new ArrayList<Stmt>();
Set<Stmt> doneSet = new HashSet<Stmt>();
workList.add(newStmt);

Set<Local> aliasingLocals = new HashSet<Local>();
aliasingLocals.add((Local) newStmt.getLeftOp());

while (!workList.isEmpty()) {
Stmt curStmt = (Stmt) workList.remove(0);
if (!doneSet.add(curStmt)) {
continue;

Check warning on line 68 in sootup.core/src/main/java/sootup/core/validation/NewValidator.java

View check run for this annotation

Codecov / codecov/patch

sootup.core/src/main/java/sootup/core/validation/NewValidator.java#L68

Added line #L68 was not covered by tests
}
if (!newStmt.equals(curStmt)) {
if (curStmt.containsInvokeExpr()) {
AbstractInvokeExpr expr = curStmt.getInvokeExpr();
if (!(expr instanceof JSpecialInvokeExpr)) {
exception.add(

Check warning on line 74 in sootup.core/src/main/java/sootup/core/validation/NewValidator.java

View check run for this annotation

Codecov / codecov/patch

sootup.core/src/main/java/sootup/core/validation/NewValidator.java#L74

Added line #L74 was not covered by tests
new ValidationException(
curStmt.getInvokeExpr(),

Check warning on line 76 in sootup.core/src/main/java/sootup/core/validation/NewValidator.java

View check run for this annotation

Codecov / codecov/patch

sootup.core/src/main/java/sootup/core/validation/NewValidator.java#L76

Added line #L76 was not covered by tests
"<init> methodRef calls may only be used with specialinvoke.")); // At least we
// found an initializer, so we return true...
return true;

Check warning on line 79 in sootup.core/src/main/java/sootup/core/validation/NewValidator.java

View check run for this annotation

Codecov / codecov/patch

sootup.core/src/main/java/sootup/core/validation/NewValidator.java#L79

Added line #L79 was not covered by tests
}
if (!(curStmt instanceof JInvokeStmt)) {
exception.add(

Check warning on line 82 in sootup.core/src/main/java/sootup/core/validation/NewValidator.java

View check run for this annotation

Codecov / codecov/patch

sootup.core/src/main/java/sootup/core/validation/NewValidator.java#L82

Added line #L82 was not covered by tests
new ValidationException(
curStmt.getInvokeExpr(),

Check warning on line 84 in sootup.core/src/main/java/sootup/core/validation/NewValidator.java

View check run for this annotation

Codecov / codecov/patch

sootup.core/src/main/java/sootup/core/validation/NewValidator.java#L84

Added line #L84 was not covered by tests
"<init> methods may only be called with invoke statements.")); // At least we
// found an initializer, so we return true...
return true;

Check warning on line 87 in sootup.core/src/main/java/sootup/core/validation/NewValidator.java

View check run for this annotation

Codecov / codecov/patch

sootup.core/src/main/java/sootup/core/validation/NewValidator.java#L87

Added line #L87 was not covered by tests
}

JSpecialInvokeExpr invoke = (JSpecialInvokeExpr) expr;
if (aliasingLocals.contains(invoke.getBase())) {
// We are happy now,continue the loop and check other paths
continue;
}
}

// We are still in the loop, so this was not the constructor call we were looking for
boolean creatingAlias = false;

Check warning on line 98 in sootup.core/src/main/java/sootup/core/validation/NewValidator.java

View check run for this annotation

Codecov / codecov/patch

sootup.core/src/main/java/sootup/core/validation/NewValidator.java#L98

Added line #L98 was not covered by tests
if (curStmt instanceof JAssignStmt) {
JAssignStmt assignCheck = (JAssignStmt) curStmt;

Check warning on line 100 in sootup.core/src/main/java/sootup/core/validation/NewValidator.java

View check run for this annotation

Codecov / codecov/patch

sootup.core/src/main/java/sootup/core/validation/NewValidator.java#L100

Added line #L100 was not covered by tests
if (aliasingLocals.contains(assignCheck.getRightOp())) {
if (assignCheck.getLeftOp() instanceof Local) {
// A new alias is created.
aliasingLocals.add((Local) assignCheck.getLeftOp());
creatingAlias = true;

Check warning on line 105 in sootup.core/src/main/java/sootup/core/validation/NewValidator.java

View check run for this annotation

Codecov / codecov/patch

sootup.core/src/main/java/sootup/core/validation/NewValidator.java#L104-L105

Added lines #L104 - L105 were not covered by tests
}
}
Local originalLocal = aliasingLocals.iterator().next();

Check warning on line 108 in sootup.core/src/main/java/sootup/core/validation/NewValidator.java

View check run for this annotation

Codecov / codecov/patch

sootup.core/src/main/java/sootup/core/validation/NewValidator.java#L108

Added line #L108 was not covered by tests
if (originalLocal.equals(assignCheck.getLeftOp())) { // In case of dead assignments:

// Handles cases like // $r0 = new x; // $r0 = null;

// But not cases like // $r0 = new x; // $r1 = $r0; // $r1 = null; // Because we check
// for the original local
continue;

Check warning on line 115 in sootup.core/src/main/java/sootup/core/validation/NewValidator.java

View check run for this annotation

Codecov / codecov/patch

sootup.core/src/main/java/sootup/core/validation/NewValidator.java#L115

Added line #L115 was not covered by tests
} else {
// Since the local on the left hand side gets overwritten
// even if it was aliasing with our original local,
// now it does not any more...
aliasingLocals.remove(assignCheck.getLeftOp());

Check warning on line 120 in sootup.core/src/main/java/sootup/core/validation/NewValidator.java

View check run for this annotation

Codecov / codecov/patch

sootup.core/src/main/java/sootup/core/validation/NewValidator.java#L120

Added line #L120 was not covered by tests
}
}

if (!creatingAlias) {
for (Value box : curStmt.getUses()) {
if (aliasingLocals.contains(box)) {
// The current unit uses one of the aliasing locals, but
// there was no initializer in between.
// However, when creating such an alias, the use is okay.
exception.add(

Check warning on line 130 in sootup.core/src/main/java/sootup/core/validation/NewValidator.java

View check run for this annotation

Codecov / codecov/patch

sootup.core/src/main/java/sootup/core/validation/NewValidator.java#L130

Added line #L130 was not covered by tests
new ValidationException(
newStmt.getLeftOp(), String.format(errorMsg, newStmt, curStmt)));
return false;

Check warning on line 133 in sootup.core/src/main/java/sootup/core/validation/NewValidator.java

View check run for this annotation

Codecov / codecov/patch

sootup.core/src/main/java/sootup/core/validation/NewValidator.java#L132-L133

Added lines #L132 - L133 were not covered by tests
}
}

Check warning on line 135 in sootup.core/src/main/java/sootup/core/validation/NewValidator.java

View check run for this annotation

Codecov / codecov/patch

sootup.core/src/main/java/sootup/core/validation/NewValidator.java#L135

Added line #L135 was not covered by tests
}
}
// Enqueue the successors
List successors = g.successors(curStmt);
if (successors.isEmpty() && MUST_CALL_CONSTRUCTOR_BEFORE_RETURN) {
// This means that we are e.g.at the end of
// the methodRef // There was no <init> call
// on our way...
exception.add(

Check warning on line 144 in sootup.core/src/main/java/sootup/core/validation/NewValidator.java

View check run for this annotation

Codecov / codecov/patch

sootup.core/src/main/java/sootup/core/validation/NewValidator.java#L144

Added line #L144 was not covered by tests
new ValidationException(
newStmt.getLeftOp(), String.format(errorMsg, newStmt, curStmt)));
return false;

Check warning on line 147 in sootup.core/src/main/java/sootup/core/validation/NewValidator.java

View check run for this annotation

Codecov / codecov/patch

sootup.core/src/main/java/sootup/core/validation/NewValidator.java#L146-L147

Added lines #L146 - L147 were not covered by tests
}
workList.addAll(successors);
}
return true;
}

@Override
Expand Down
Loading