Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package io.codemodder.remediation.missingsecureflag;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.expr.BooleanLiteralExpr;
import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.ast.expr.MethodCallExpr;
import com.github.javaparser.ast.stmt.ExpressionStmt;
import com.github.javaparser.ast.stmt.Statement;
import io.codemodder.CodemodChange;
import io.codemodder.CodemodFileScanningResult;
import io.codemodder.ast.ASTTransforms;
import io.codemodder.codetf.DetectorRule;
import io.codemodder.codetf.FixedFinding;
import io.codemodder.codetf.UnfixedFinding;
import io.codemodder.remediation.LegacyFixCandidate;
import io.codemodder.remediation.LegacyFixCandidateSearchResults;
import io.codemodder.remediation.LegacyFixCandidateSearcher;
import io.codemodder.remediation.RemediationMessages;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
import org.jetbrains.annotations.NotNull;
final class DefaultMissingSecureFlagRemediator implements MissingSecureFlagRemediator {
@Override
public CodemodFileScanningResult remediateAll(
final CompilationUnit cu,
final String path,
final DetectorRule detectorRule,
final List issuesForFile,
final Function getKey,
final Function getStartLine,
final Function getEndLine,
final Function getStartColumn) {
// this remediator assumes we're pointing to a response.addCookie() call
LegacyFixCandidateSearcher searcher =
new LegacyFixCandidateSearcher.Builder()
.withMethodName("addCookie")
.withMatcher(mce -> mce.getArguments().size() == 1)
.build();
LegacyFixCandidateSearchResults results =
searcher.search(
cu,
path,
detectorRule,
issuesForFile,
getKey,
getStartLine,
getEndLine,
getStartColumn);
List changes = new ArrayList<>();
List unfixedFindings = new ArrayList<>();
for (LegacyFixCandidate result : results.fixCandidates()) {
MethodCallExpr methodCallExpr = result.call().asMethodCall();
List issues = result.issues();
if (methodCallExpr.getScope().isPresent()) {
// This assumption is a bit strong, but covers the most common cases while avoiding weird
// ones
Optional maybeStmt =
methodCallExpr
.getParentNode()
.map(p -> p instanceof Statement ? (Statement) p : null)
.filter(Statement::isExpressionStmt);
// We want to avoid things like: response.addCookie(new Cookie(...)), so we restrict
// ourselves
Optional maybeCookieExpression =
Optional.of(methodCallExpr.getArgument(0))
.filter(expr -> expr.isNameExpr() || expr.isFieldAccessExpr());
if (maybeStmt.isPresent() && maybeCookieExpression.isPresent()) {
final var newStatement =
new ExpressionStmt(
new MethodCallExpr(
maybeCookieExpression.get(),
"setSecure",
new NodeList<>(new BooleanLiteralExpr(true))));
ASTTransforms.addStatementBeforeStatement(maybeStmt.get(), newStatement);
FixedFinding fixedFinding = new FixedFinding(getKey.apply(issues.get(0)), detectorRule);
CodemodChange change =
CodemodChange.from(
result.call().getRange().begin.line, List.of(), List.of(fixedFinding));
changes.add(change);
} else {
List unfixedFindingsToAdd =
createUnfixedFindingList(path, detectorRule, getKey, getStartLine, issues);
unfixedFindings.addAll(unfixedFindingsToAdd);
}
} else {
List unfixedFindingsToAdd =
createUnfixedFindingList(path, detectorRule, getKey, getStartLine, issues);
unfixedFindings.addAll(unfixedFindingsToAdd);
}
}
return CodemodFileScanningResult.from(changes, unfixedFindings);
}
private static @NotNull List createUnfixedFindingList(
final String path,
final DetectorRule detectorRule,
final Function getKey,
final Function getStartLine,
final List issues) {
return issues.stream()
.map(
issue ->
new UnfixedFinding(
getKey.apply(issue),
detectorRule,
path,
getStartLine.apply(issue),
RemediationMessages.ambiguousCodeShape))
.toList();
}
}