io.codemodder.codemods.LimitReadlineCodemod Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of core-codemods Show documentation
Show all versions of core-codemods Show documentation
Codemods for fixing common errors across many Java projects
package io.codemodder.codemods;
import com.contrastsecurity.sarif.Result;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.ast.expr.IntegerLiteralExpr;
import com.github.javaparser.ast.expr.MethodCallExpr;
import com.github.javaparser.ast.expr.NameExpr;
import io.codemodder.*;
import io.codemodder.ast.ASTTransforms;
import io.codemodder.javaparser.ChangesResult;
import io.codemodder.providers.sarif.semgrep.SemgrepScan;
import io.github.pixee.security.BoundedLineReader;
import java.util.List;
import java.util.Objects;
import javax.inject.Inject;
/** Turns hardcoded seeds for PRNGs to be more random. */
@Codemod(
id = "pixee:java/limit-readline",
importance = Importance.MEDIUM,
reviewGuidance = ReviewGuidance.MERGE_WITHOUT_REVIEW)
public final class LimitReadlineCodemod extends SarifPluginJavaParserChanger {
private final Parameter limit;
@Inject
public LimitReadlineCodemod(
@SemgrepScan(ruleId = "limit-readline") final RuleSarif sarif,
@CodemodParameter(
question =
"What is the maximum number of characters that should be allowed to be read from the reader?",
name = "limit",
type = CodemodParameter.ParameterType.NUMBER,
label = "a positive integer",
defaultValue = "5_000_000", // representing roughly 5MB
validationPattern = "[0-9\\_]+")
final Parameter limit) {
super(sarif, MethodCallExpr.class);
this.limit = Objects.requireNonNull(limit);
}
@Override
public ChangesResult onResultFound(
final CodemodInvocationContext context,
final CompilationUnit cu,
final MethodCallExpr readLineCall,
final Result result) {
Node readLineParent = readLineCall.getParentNode().get();
Expression readerScope = readLineCall.getScope().get();
MethodCallExpr safeExpression =
new MethodCallExpr(new NameExpr(BoundedLineReader.class.getSimpleName()), "readLine");
int line = readLineCall.getRange().get().begin.line;
String stringLimitValue = limit.getValue(context.path(), line);
safeExpression.setArguments(
NodeList.nodeList(readerScope, new IntegerLiteralExpr(stringLimitValue)));
ASTTransforms.addImportIfMissing(cu, BoundedLineReader.class);
readLineParent.replace(readLineCall, safeExpression);
return ChangesResult.changesAppliedWith(List.of(DependencyGAV.JAVA_SECURITY_TOOLKIT));
}
}