Skip to content

Commit 38b925b

Browse files
committed
rename "use matches" query, and refactor into Query.qll
1 parent 89604de commit 38b925b

File tree

2 files changed

+40
-13
lines changed

2 files changed

+40
-13
lines changed

ql/src/queries/performance/PrefixSuffixEquality.ql renamed to ql/src/codeql_ql/performance/InefficientStringComparisonQuery.qll

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,3 @@
1-
/**
2-
* @name Prefix or suffix predicate calls when comparing with literal
3-
* @description Using 'myString.prefix(n) = "..."' instead of 'myString.matches("...%")'
4-
* @kind problem
5-
* @problem.severity error
6-
* @id ql/prefix-or-suffix-equality-check
7-
* @tags performance
8-
* @precision high
9-
*/
10-
111
import ql
122
import codeql_ql.ast.internal.Predicate
133
import codeql_ql.ast.internal.Builtins
@@ -48,6 +38,17 @@ class FixPredicateCall extends Call {
4838
FixPredicateCall() { this instanceof PrefixPredicateCall or this instanceof SuffixPredicateCall }
4939
}
5040

51-
from EqFormula eq, FixPredicateCall call, String literal
52-
where eq.getAnOperand() = call and eq.getAnOperand() = literal
53-
select eq, "Use " + getMessage(call, literal) + " instead."
41+
class RegexpMatchPredicate extends BuiltinPredicate {
42+
RegexpMatchPredicate() { this = any(StringClass sc).getClassPredicate("regexpMatch", 1) }
43+
}
44+
45+
predicate canUseMatchInsteadOfRegexpMatch(Call c, string matchesStr) {
46+
c.getTarget() instanceof RegexpMatchPredicate and
47+
exists(string raw | raw = c.getArgument(0).(String).getValue() |
48+
matchesStr = "%" + raw.regexpCapture("^\\.\\*(\\w+)$", _)
49+
or
50+
matchesStr = raw.regexpCapture("^(\\w+)\\.\\*$", _) + "%"
51+
or
52+
matchesStr = "%" + raw.regexpCapture("^\\.\\*(\\w+)\\.\\*$", _) + "%"
53+
)
54+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**
2+
* @name Inefficient string comparison
3+
* @description The `.matches` predicate is usually the best performing way to compare strings.
4+
* @kind problem
5+
* @problem.severity error
6+
* @id ql/inefficient-string-comparison
7+
* @tags performance
8+
* @precision high
9+
*/
10+
11+
import ql
12+
import codeql_ql.performance.InefficientStringComparisonQuery
13+
14+
from AstNode node, string msg
15+
where
16+
exists(EqFormula eq, FixPredicateCall call, String literal |
17+
node = eq and msg = "Use " + getMessage(call, literal) + " instead."
18+
|
19+
eq.getAnOperand() = call and eq.getAnOperand() = literal
20+
)
21+
or
22+
exists(string matchesStr |
23+
canUseMatchInsteadOfRegexpMatch(node, matchesStr) and
24+
msg = "Use matches(\"" + matchesStr + "\") instead"
25+
)
26+
select node, msg

0 commit comments

Comments
 (0)