mirror of
https://github.com/github/codeql.git
synced 2025-12-22 11:46:32 +01:00
56 lines
1.5 KiB
Plaintext
56 lines
1.5 KiB
Plaintext
/**
|
|
* @name String concatenation in loop
|
|
* @description Finds code that performs string concatenation in a loop using the + operator.
|
|
* @kind problem
|
|
* @problem.severity recommendation
|
|
* @precision very-high
|
|
* @id cs/string-concatenation-in-loop
|
|
* @tags efficiency
|
|
* maintainability
|
|
*/
|
|
|
|
import csharp
|
|
|
|
// any use of + that has string type
|
|
class StringCat extends AddExpr {
|
|
StringCat() { this.getType() instanceof StringType }
|
|
}
|
|
|
|
/**
|
|
* Holds if `e` is an assignment of the form
|
|
* `v = ... + ... v ...`
|
|
* where `v` is a simple variable (and not, for example, a property).
|
|
*/
|
|
predicate isSelfConcatAssignExpr(AssignExpr e, Variable v) {
|
|
not e = any(AssignAddExpr a).getExpandedAssignment() and
|
|
exists(VariableAccess use |
|
|
stringCatContains(e.getRValue(), use) and
|
|
use.getTarget() = e.getTargetVariable() and
|
|
v = use.getTarget()
|
|
)
|
|
}
|
|
|
|
predicate stringCatContains(StringCat expr, Expr child) {
|
|
child = expr or
|
|
stringCatContains(expr, child.getParent())
|
|
}
|
|
|
|
/**
|
|
* Holds if `e` is an assignment of the form
|
|
* `v += ...`
|
|
* where `v` is a simple variable (and not, for example, a property).
|
|
*/
|
|
predicate isConcatExpr(AssignAddExpr e, Variable v) {
|
|
e.getLValue().getType() instanceof StringType and
|
|
v = e.getTargetVariable()
|
|
}
|
|
|
|
from Expr e
|
|
where
|
|
exists(LoopStmt loop, Variable v |
|
|
e.getEnclosingStmt().getParent*() = loop and
|
|
(isSelfConcatAssignExpr(e, v) or isConcatExpr(e, v)) and
|
|
forall(LocalVariableDeclExpr l | l.getVariable() = v | not l.getParent*() = loop)
|
|
)
|
|
select e, "String concatenation in loop: use 'StringBuilder'."
|