Skip to content

Commit de81008

Browse files
committed
Tweaked transformation to not close if the execute is the first usage
1 parent 8fbaed8 commit de81008

File tree

1 file changed

+28
-4
lines changed

1 file changed

+28
-4
lines changed

framework/codemodder-base/src/main/java/io/codemodder/remediation/sqlinjection/SQLParameterizer.java

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -708,10 +708,17 @@ private MethodCallExpr fixByHijackedStatement(
708708
ASTTransforms.addStatementBeforeStatement(topStatement, pStmtCreation);
709709
topStatement = pStmtCreation;
710710

711-
// add stmt.close()
712-
Statement closeOriginal =
713-
new ExpressionStmt(new MethodCallExpr(new NameExpr(stmtName), new SimpleName("close")));
714-
ASTTransforms.addStatementBeforeStatement(topStatement, closeOriginal);
711+
// Test if stmt.execute*() is the first usage of the stmt object
712+
// If so, remove initializer
713+
// otherwise add stmt.close()
714+
if (isExecuteFirstUsageAfterDeclaration(stmtCreation, executeCall)) {
715+
var lvd = stmtCreation.getRight();
716+
lvd.getVariableDeclarator().getInitializer().ifPresent(i -> i.remove());
717+
} else {
718+
Statement closeOriginal =
719+
new ExpressionStmt(new MethodCallExpr(new NameExpr(stmtName), new SimpleName("close")));
720+
ASTTransforms.addStatementBeforeStatement(topStatement, closeOriginal);
721+
}
715722

716723
// TODO will this work for every type of execute statement? or just executeQuery?
717724
// change execute statement
@@ -729,6 +736,23 @@ private MethodCallExpr fixByHijackedStatement(
729736
return prepareStatementCall;
730737
}
731738

739+
private boolean isExecuteFirstUsageAfterDeclaration(
740+
final Either<AssignExpr, LocalVariableDeclaration> stmtCreation,
741+
final MethodCallExpr executeCall) {
742+
if (stmtCreation.isRight()) {
743+
var lvd = stmtCreation.getRight();
744+
// This is heuristics
745+
return ASTs.findAllReferences(lvd).stream()
746+
.findFirst()
747+
.flatMap(e -> ASTs.isScopeInMethodCall(e))
748+
.filter(mce -> mce == executeCall)
749+
.isPresent();
750+
}
751+
// We could also apply this predicate to assignments and remove it, but that may require more
752+
// checks
753+
return false;
754+
}
755+
732756
/**
733757
* Checks if {@code methodCall} is a query call that needs to be fixed and fixes if that's the
734758
* case. If the parameterization happened, returns the PreparedStatement creation.

0 commit comments

Comments
 (0)