rename "use matches" query, and refactor into Query.qll

This commit is contained in:
Erik Krogh Kristensen
2021-11-18 13:05:41 +01:00
parent 89604deb8d
commit 38b925b19c
2 changed files with 40 additions and 13 deletions

View File

@@ -1,13 +1,3 @@
/**
* @name Prefix or suffix predicate calls when comparing with literal
* @description Using 'myString.prefix(n) = "..."' instead of 'myString.matches("...%")'
* @kind problem
* @problem.severity error
* @id ql/prefix-or-suffix-equality-check
* @tags performance
* @precision high
*/
import ql
import codeql_ql.ast.internal.Predicate
import codeql_ql.ast.internal.Builtins
@@ -48,6 +38,17 @@ class FixPredicateCall extends Call {
FixPredicateCall() { this instanceof PrefixPredicateCall or this instanceof SuffixPredicateCall }
}
from EqFormula eq, FixPredicateCall call, String literal
where eq.getAnOperand() = call and eq.getAnOperand() = literal
select eq, "Use " + getMessage(call, literal) + " instead."
class RegexpMatchPredicate extends BuiltinPredicate {
RegexpMatchPredicate() { this = any(StringClass sc).getClassPredicate("regexpMatch", 1) }
}
predicate canUseMatchInsteadOfRegexpMatch(Call c, string matchesStr) {
c.getTarget() instanceof RegexpMatchPredicate and
exists(string raw | raw = c.getArgument(0).(String).getValue() |
matchesStr = "%" + raw.regexpCapture("^\\.\\*(\\w+)$", _)
or
matchesStr = raw.regexpCapture("^(\\w+)\\.\\*$", _) + "%"
or
matchesStr = "%" + raw.regexpCapture("^\\.\\*(\\w+)\\.\\*$", _) + "%"
)
}

View File

@@ -0,0 +1,26 @@
/**
* @name Inefficient string comparison
* @description The `.matches` predicate is usually the best performing way to compare strings.
* @kind problem
* @problem.severity error
* @id ql/inefficient-string-comparison
* @tags performance
* @precision high
*/
import ql
import codeql_ql.performance.InefficientStringComparisonQuery
from AstNode node, string msg
where
exists(EqFormula eq, FixPredicateCall call, String literal |
node = eq and msg = "Use " + getMessage(call, literal) + " instead."
|
eq.getAnOperand() = call and eq.getAnOperand() = literal
)
or
exists(string matchesStr |
canUseMatchInsteadOfRegexpMatch(node, matchesStr) and
msg = "Use matches(\"" + matchesStr + "\") instead"
)
select node, msg