Skip to content

Commit fff70da

Browse files
authored
Merge pull request #9182 from erik-krogh/useStringComp
use string equality instead of regexps to compare constant strings
2 parents eef5022 + 215a6a7 commit fff70da

File tree

27 files changed

+94
-62
lines changed

27 files changed

+94
-62
lines changed

cpp/ql/lib/semmle/code/cpp/commons/Printf.qll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -872,7 +872,7 @@ class FormatLiteral extends Literal {
872872

873873
private Type getConversionType1(int n) {
874874
exists(string cnv | cnv = this.getConversionChar(n) |
875-
cnv.regexpMatch("d|i") and
875+
cnv = ["d", "i"] and
876876
result = this.getIntegralConversion(n) and
877877
not result.getUnderlyingType().(IntegralType).isExplicitlySigned() and
878878
not result.getUnderlyingType().(IntegralType).isExplicitlyUnsigned()
@@ -912,15 +912,15 @@ class FormatLiteral extends Literal {
912912

913913
private Type getConversionType2(int n) {
914914
exists(string cnv | cnv = this.getConversionChar(n) |
915-
cnv.regexpMatch("o|u|x|X") and
915+
cnv = ["o", "u", "x", "X"] and
916916
result = this.getIntegralConversion(n) and
917917
result.getUnderlyingType().(IntegralType).isUnsigned()
918918
)
919919
}
920920

921921
private Type getConversionType3(int n) {
922922
exists(string cnv | cnv = this.getConversionChar(n) |
923-
cnv.regexpMatch("a|A|e|E|f|F|g|G") and result = this.getFloatingPointConversion(n)
923+
cnv = ["a", "A", "e", "E", "f", "F", "g", "G"] and result = this.getFloatingPointConversion(n)
924924
)
925925
}
926926

cpp/ql/src/Likely Bugs/Conversion/LossyFunctionResultCast.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ predicate whitelist(Function f) {
1919
"nearbyintl", "rint", "rintf", "rintl", "round", "roundf", "roundl", "trunc", "truncf",
2020
"truncl"
2121
] or
22-
f.getName().matches("__builtin_%")
22+
f.getName().matches("\\_\\_builtin\\_%")
2323
}
2424

2525
predicate whitelistPow(FunctionCall fc) {

cpp/ql/src/experimental/Security/CWE/CWE-266/IncorrectPrivilegeAssignment.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ where
5858
// unfortunately cannot use numeric value here because // O_CREAT is defined differently on different OSes:
5959
// https://github.com/red/red/blob/92feb0c0d5f91e087ab35fface6906afbf99b603/runtime/definitions.reds#L477-L491
6060
// this may introduce false negatives
61-
fctmp.getArgument(1).(BitwiseOrExpr).getAChild*().getValueText().matches("O_CREAT") or
61+
fctmp.getArgument(1).(BitwiseOrExpr).getAChild*().getValueText() = "O_CREAT" or
6262
fctmp.getArgument(1).getValueText().matches("%O_CREAT%")
6363
) and
6464
fctmp.getNumberOfArguments() = 2 and

cpp/ql/src/jsf/4.05 Libraries/AV Rule 23.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import cpp
1313

1414
from Function f
1515
where
16-
f.getName().regexpMatch("atof|atoi|atol") and
16+
f.getName() = ["atof", "atoi", "atol"] and
1717
f.getFile().getAbsolutePath().matches("%stdlib.h")
1818
select f.getACallToThisFunction(),
1919
"AV Rule 23: The library functions atof, atoi and atol from library <stdlib.h> shall not be used."

cpp/ql/src/jsf/4.05 Libraries/AV Rule 24.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import cpp
1313

1414
from Function f
1515
where
16-
f.getName().regexpMatch("abort|exit|getenv|system") and
16+
f.getName() = ["abort", "exit", "getenv", "system"] and
1717
f.getFile().getAbsolutePath().matches("%stdlib.h")
1818
select f.getACallToThisFunction(),
1919
"The library functions abort, exit, getenv and system from library <stdlib.h> should not be used."

csharp/ql/src/Likely Bugs/LeapYear/UnsafeYearConstruction.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class UnsafeYearCreationFromArithmeticConfiguration extends TaintTracking::Confi
2020
override predicate isSource(DataFlow::Node source) {
2121
exists(ArithmeticOperation ao, PropertyAccess pa | ao = source.asExpr() |
2222
pa = ao.getAChild*() and
23-
pa.getProperty().getQualifiedName().matches("System.DateTime.Year")
23+
pa.getProperty().hasQualifiedName("System.DateTime.Year")
2424
)
2525
}
2626

java/ql/lib/semmle/code/java/Collections.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ class CollectionMutation extends MethodAccess {
9292
/** A method that queries the contents of a collection without mutating it. */
9393
class CollectionQueryMethod extends CollectionMethod {
9494
CollectionQueryMethod() {
95-
pragma[only_bind_into](this).getName().regexpMatch("contains|containsAll|get|size|peek")
95+
pragma[only_bind_into](this).getName() = ["contains", "containsAll", "get", "size", "peek"]
9696
}
9797
}
9898

java/ql/lib/semmle/code/java/Maps.qll

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,8 @@ class MapMutation extends MethodAccess {
5959
/** A method that queries the contents of the map it belongs to without mutating it. */
6060
class MapQueryMethod extends MapMethod {
6161
MapQueryMethod() {
62-
pragma[only_bind_into](this)
63-
.getName()
64-
.regexpMatch("get|containsKey|containsValue|entrySet|keySet|values|isEmpty|size")
62+
pragma[only_bind_into](this).getName() =
63+
["get", "containsKey", "containsValue", "entrySet", "keySet", "values", "isEmpty", "size"]
6564
}
6665
}
6766

java/ql/lib/semmle/code/java/Type.qll

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,7 +1002,9 @@ class FunctionalInterface extends Interface {
10021002
* and `double`.
10031003
*/
10041004
class PrimitiveType extends Type, @primitive {
1005-
PrimitiveType() { this.getName().regexpMatch("float|double|int|boolean|short|byte|char|long") }
1005+
PrimitiveType() {
1006+
this.getName() = ["float", "double", "int", "boolean", "short", "byte", "char", "long"]
1007+
}
10061008

10071009
/** Gets the boxed type corresponding to this primitive type. */
10081010
BoxedType getBoxedType() { result.getPrimitiveType() = this }
@@ -1217,9 +1219,9 @@ predicate erasedHaveIntersection(RefType t1, RefType t2) {
12171219
class IntegralType extends Type {
12181220
IntegralType() {
12191221
exists(string name |
1220-
name = this.(PrimitiveType).getName() or name = this.(BoxedType).getPrimitiveType().getName()
1222+
name = [this.(PrimitiveType).getName(), this.(BoxedType).getPrimitiveType().getName()]
12211223
|
1222-
name.regexpMatch("byte|char|short|int|long")
1224+
name = ["byte", "char", "short", "int", "long"]
12231225
)
12241226
}
12251227
}
@@ -1228,7 +1230,7 @@ class IntegralType extends Type {
12281230
class BooleanType extends Type {
12291231
BooleanType() {
12301232
exists(string name |
1231-
name = this.(PrimitiveType).getName() or name = this.(BoxedType).getPrimitiveType().getName()
1233+
name = [this.(PrimitiveType).getName(), this.(BoxedType).getPrimitiveType().getName()]
12321234
|
12331235
name = "boolean"
12341236
)
@@ -1239,7 +1241,7 @@ class BooleanType extends Type {
12391241
class CharacterType extends Type {
12401242
CharacterType() {
12411243
exists(string name |
1242-
name = this.(PrimitiveType).getName() or name = this.(BoxedType).getPrimitiveType().getName()
1244+
name = [this.(PrimitiveType).getName(), this.(BoxedType).getPrimitiveType().getName()]
12431245
|
12441246
name = "char"
12451247
)
@@ -1250,10 +1252,9 @@ class CharacterType extends Type {
12501252
class NumericType extends Type {
12511253
NumericType() {
12521254
exists(string name |
1253-
name = this.(PrimitiveType).getName() or
1254-
name = this.(BoxedType).getPrimitiveType().getName()
1255+
name = [this.(PrimitiveType).getName(), this.(BoxedType).getPrimitiveType().getName()]
12551256
|
1256-
name.regexpMatch("byte|short|int|long|double|float")
1257+
name = ["byte", "short", "int", "long", "double", "float"]
12571258
)
12581259
}
12591260
}
@@ -1262,9 +1263,9 @@ class NumericType extends Type {
12621263
class NumericOrCharType extends Type {
12631264
NumericOrCharType() {
12641265
exists(string name |
1265-
name = this.(PrimitiveType).getName() or name = this.(BoxedType).getPrimitiveType().getName()
1266+
name = [this.(PrimitiveType).getName(), this.(BoxedType).getPrimitiveType().getName()]
12661267
|
1267-
name.regexpMatch("byte|char|short|int|long|double|float")
1268+
name = ["byte", "char", "short", "int", "long", "double", "float"]
12681269
)
12691270
}
12701271
}
@@ -1273,9 +1274,9 @@ class NumericOrCharType extends Type {
12731274
class FloatingPointType extends Type {
12741275
FloatingPointType() {
12751276
exists(string name |
1276-
name = this.(PrimitiveType).getName() or name = this.(BoxedType).getPrimitiveType().getName()
1277+
name = [this.(PrimitiveType).getName(), this.(BoxedType).getPrimitiveType().getName()]
12771278
|
1278-
name.regexpMatch("float|double")
1279+
name = ["float", "double"]
12791280
)
12801281
}
12811282
}

java/ql/lib/semmle/code/java/dataflow/RangeAnalysis.qll

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -337,15 +337,15 @@ private predicate safeCast(Type fromtyp, Type totyp) {
337337
exists(PrimitiveType pfrom, PrimitiveType pto | pfrom = fromtyp and pto = totyp |
338338
pfrom = pto
339339
or
340-
pfrom.hasName("char") and pto.getName().regexpMatch("int|long|float|double")
340+
pfrom.hasName("char") and pto.hasName(["int", "long", "float", "double"])
341341
or
342-
pfrom.hasName("byte") and pto.getName().regexpMatch("short|int|long|float|double")
342+
pfrom.hasName("byte") and pto.hasName(["short", "int", "long", "float", "double"])
343343
or
344-
pfrom.hasName("short") and pto.getName().regexpMatch("int|long|float|double")
344+
pfrom.hasName("short") and pto.hasName(["int", "long", "float", "double"])
345345
or
346-
pfrom.hasName("int") and pto.getName().regexpMatch("long|float|double")
346+
pfrom.hasName("int") and pto.hasName(["long", "float", "double"])
347347
or
348-
pfrom.hasName("long") and pto.getName().regexpMatch("float|double")
348+
pfrom.hasName("long") and pto.hasName(["float", "double"])
349349
or
350350
pfrom.hasName("float") and pto.hasName("double")
351351
or

java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ private predicate localAdditionalTaintUpdateStep(Expr src, Expr sink) {
190190

191191
private class BulkData extends RefType {
192192
BulkData() {
193-
this.(Array).getElementType().(PrimitiveType).getName().regexpMatch("byte|char")
193+
this.(Array).getElementType().(PrimitiveType).hasName(["byte", "char"])
194194
or
195195
exists(RefType t | this.getASourceSupertype*() = t |
196196
t.hasQualifiedName("java.io", "InputStream") or
@@ -321,15 +321,15 @@ private predicate argToMethodStep(Expr tracked, MethodAccess sink) {
321321
exists(Method springResponseEntityOfOk |
322322
sink.getMethod() = springResponseEntityOfOk and
323323
springResponseEntityOfOk.getDeclaringType() instanceof SpringResponseEntity and
324-
springResponseEntityOfOk.getName().regexpMatch("ok|of") and
324+
springResponseEntityOfOk.hasName(["ok", "of"]) and
325325
tracked = sink.getArgument(0) and
326326
tracked.getType() instanceof TypeString
327327
)
328328
or
329329
exists(Method springResponseEntityBody |
330330
sink.getMethod() = springResponseEntityBody and
331331
springResponseEntityBody.getDeclaringType() instanceof SpringResponseEntityBodyBuilder and
332-
springResponseEntityBody.getName().regexpMatch("body") and
332+
springResponseEntityBody.hasName("body") and
333333
tracked = sink.getArgument(0) and
334334
tracked.getType() instanceof TypeString
335335
)

java/ql/lib/semmle/code/java/deadcode/frameworks/FitNesseEntryPoints.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class FitFixtureEntryPoint extends CallableEntryPoint {
1313
* FitNesse entry points externally defined.
1414
*/
1515
class FitNesseSlimEntryPointData extends ExternalData {
16-
FitNesseSlimEntryPointData() { getDataPath().matches("fitnesse.csv") }
16+
FitNesseSlimEntryPointData() { getDataPath() = "fitnesse.csv" }
1717

1818
/**
1919
* Gets the class name.

java/ql/lib/semmle/code/java/frameworks/Mockito.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ class MockitoInitedTest extends Class {
8585
*/
8686
class MockitoAnnotation extends Annotation {
8787
MockitoAnnotation() {
88-
this.getType().getPackage().getName().matches("org.mockito") or
88+
this.getType().getPackage().hasName("org.mockito") or
8989
this.getType().getPackage().getName().matches("org.mockito.%")
9090
}
9191
}

java/ql/lib/semmle/code/java/frameworks/android/Slice.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ private class SliceProviderLifecycleStep extends AdditionalValueStep {
3737

3838
private class SliceActionsInheritTaint extends DataFlow::SyntheticFieldContent,
3939
TaintInheritingContent {
40-
SliceActionsInheritTaint() { this.getField().matches("androidx.slice.Slice.action") }
40+
SliceActionsInheritTaint() { this.getField() = "androidx.slice.Slice.action" }
4141
}
4242

4343
private class SliceBuildersSummaryModels extends SummaryModelCsv {

java/ql/lib/semmle/code/java/security/ExternalAPIs.qll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ private class DefaultSafeExternalApiMethod extends SafeExternalApiMethod {
2020
DefaultSafeExternalApiMethod() {
2121
this instanceof EqualsMethod
2222
or
23-
this.getName().regexpMatch("size|length|compareTo|getClass|lastIndexOf")
23+
this.hasName(["size", "length", "compareTo", "getClass", "lastIndexOf"])
2424
or
2525
this.getDeclaringType().hasQualifiedName("org.apache.commons.lang3", "Validate")
2626
or
@@ -42,7 +42,7 @@ private class DefaultSafeExternalApiMethod extends SafeExternalApiMethod {
4242
this.getName() = "isDigit"
4343
or
4444
this.getDeclaringType().hasQualifiedName("java.lang", "String") and
45-
this.getName().regexpMatch("equalsIgnoreCase|regionMatches")
45+
this.hasName(["equalsIgnoreCase", "regionMatches"])
4646
or
4747
this.getDeclaringType().hasQualifiedName("java.lang", "Boolean") and
4848
this.getName() = "parseBoolean"
@@ -51,7 +51,7 @@ private class DefaultSafeExternalApiMethod extends SafeExternalApiMethod {
5151
this.getName() = "closeQuietly"
5252
or
5353
this.getDeclaringType().hasQualifiedName("org.springframework.util", "StringUtils") and
54-
this.getName().regexpMatch("hasText|isEmpty")
54+
this.hasName(["hasText", "isEmpty"])
5555
}
5656
}
5757

java/ql/src/experimental/Security/CWE/CWE-470/UnsafeReflectionLib.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ predicate looksLikeResolveClassStep(DataFlow::Node fromNode, DataFlow::Node toNo
3535
m = ma.getMethod() and arg = ma.getArgument(i)
3636
|
3737
m.getReturnType() instanceof TypeClass and
38-
m.getName().toLowerCase().regexpMatch("resolve|load|class|type") and
38+
m.getName().toLowerCase() = ["resolve", "load", "class", "type"] and
3939
arg.getType() instanceof TypeString and
4040
arg = fromNode.asExpr() and
4141
ma = toNode.asExpr()
@@ -52,7 +52,7 @@ predicate looksLikeInstantiateClassStep(DataFlow::Node fromNode, DataFlow::Node
5252
m = ma.getMethod() and arg = ma.getArgument(i)
5353
|
5454
m.getReturnType() instanceof TypeObject and
55-
m.getName().toLowerCase().regexpMatch("instantiate|instance|create|make|getbean") and
55+
m.getName().toLowerCase() = ["instantiate", "instance", "create", "make", "getbean"] and
5656
arg.getType() instanceof TypeClass and
5757
arg = fromNode.asExpr() and
5858
ma = toNode.asExpr()

java/ql/src/experimental/Security/CWE/CWE-601/SpringUrlRedirect.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,6 @@ predicate springUrlRedirectTaintStep(DataFlow::Node fromNode, DataFlow::Node toN
134134
predicate nonLocationHeaderSanitizer(DataFlow::Node node) {
135135
exists(HttpHeadersAddSetMethodAccess ma, Argument firstArg | node.asExpr() = ma.getArgument(1) |
136136
firstArg = ma.getArgument(0) and
137-
not firstArg.(CompileTimeConstantExpr).getStringValue().matches("Location")
137+
not firstArg.(CompileTimeConstantExpr).getStringValue() = "Location"
138138
)
139139
}

java/ql/src/utils/model-generator/internal/CaptureModelsSpecific.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ string asPartialModel(TargetApiSpecific api) {
111111
}
112112

113113
private predicate isPrimitiveTypeUsedForBulkData(J::Type t) {
114-
t.getName().regexpMatch("byte|char|Byte|Character")
114+
t.hasName(["byte", "char", "Byte", "Character"])
115115
}
116116

117117
/**

javascript/ql/lib/semmle/javascript/Expr.qll

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2286,9 +2286,7 @@ class ComprehensionExpr extends @comprehension_expr, Expr {
22862286

22872287
/** Holds if this is a legacy postfix comprehension expression. */
22882288
predicate isPostfix() {
2289-
exists(Token tk | tk = this.getFirstToken().getNextToken() |
2290-
not tk.getValue().regexpMatch("if|for")
2291-
)
2289+
exists(Token tk | tk = this.getFirstToken().getNextToken() | not tk.getValue() = ["if", "for"])
22922290
}
22932291

22942292
override string getAPrimaryQlClass() { result = "ComprehensionExpr" }

javascript/ql/lib/semmle/javascript/frameworks/xUnit.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ private predicate xUnitDetected() {
1919
private predicate possiblyAttribute(Expr e, string name) {
2020
exists(Identifier id | id = e or id = e.(CallExpr).getCallee() |
2121
name = id.getName() and
22-
name.regexpMatch("Async|Data|Fact|Fixture|Import|ImportJson|Skip|Trait")
22+
name = ["Async", "Data", "Fact", "Fixture", "Import", "ImportJson", "Skip", "Trait"]
2323
)
2424
}
2525

javascript/ql/src/Declarations/DeadStoreOfGlobal.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ where
2424
// 'v' is not externally declared...
2525
not exists(ExternalVarDecl d | d.getName() = v.getName() |
2626
// ...as a member of {Window,Worker,WebWorker}.prototype
27-
d.(ExternalInstanceMemberDecl).getBaseName().regexpMatch("Window|Worker|WebWorker")
27+
d.(ExternalInstanceMemberDecl).getBaseName() = ["Window", "Worker", "WebWorker"]
2828
or
2929
// ...or as a member of window
3030
d.(ExternalStaticMemberDecl).getBaseName() = "window"

javascript/ql/src/LanguageFeatures/ArgumentsCallerCallee.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import javascript
1515
from PropAccess acc, ArgumentsVariable args
1616
where
1717
acc.getBase() = args.getAnAccess() and
18-
acc.getPropertyName().regexpMatch("caller|callee") and
18+
acc.getPropertyName() = ["caller", "callee"] and
1919
// don't flag cases where the variable can never contain an arguments object
2020
not exists(Function fn | args = fn.getVariable()) and
2121
not exists(Parameter p | args = p.getAVariable()) and

javascript/ql/src/LanguageFeatures/BadTypeof.ql

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,11 @@ from EqOrSwitch et, TypeofExpr typeof, ConstantString str
5050
where
5151
typeof = et.getAnOperand().getUnderlyingValue() and
5252
str = et.getAnOperand().getUnderlyingValue() and
53-
not str.getStringValue()
54-
.regexpMatch("undefined|boolean|number|string|object|function|symbol|unknown|date|bigint")
53+
not str.getStringValue() =
54+
[
55+
"undefined", "boolean", "number", "string", "object", "function", "symbol", "unknown", "date",
56+
"bigint"
57+
]
5558
select typeof,
5659
"The result of this 'typeof' expression is compared to '$@', but the two can never be equal.",
5760
str, str.getStringValue()

python/ql/src/experimental/semmle/python/libraries/Authlib.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ private module Authlib {
4343
override DataFlow::Node getAlgorithm() {
4444
exists(KeyValuePair headerDict |
4545
headerDict = this.getArg(0).asExpr().(Dict).getItem(_) and
46-
headerDict.getKey().(Str_).getS().matches("alg") and
46+
headerDict.getKey().(Str_).getS() = "alg" and
4747
result.asExpr() = headerDict.getValue()
4848
)
4949
}

0 commit comments

Comments
 (0)