Skip to content

use string equality instead of regexps to compare constant strings #9182

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions cpp/ql/lib/semmle/code/cpp/commons/Printf.qll
Original file line number Diff line number Diff line change
Expand Up @@ -872,7 +872,7 @@ class FormatLiteral extends Literal {

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

private Type getConversionType2(int n) {
exists(string cnv | cnv = this.getConversionChar(n) |
cnv.regexpMatch("o|u|x|X") and
cnv = ["o", "u", "x", "X"] and
result = this.getIntegralConversion(n) and
result.getUnderlyingType().(IntegralType).isUnsigned()
)
}

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ predicate whitelist(Function f) {
"nearbyintl", "rint", "rintf", "rintl", "round", "roundf", "roundl", "trunc", "truncf",
"truncl"
] or
f.getName().matches("__builtin_%")
f.getName().matches("\\_\\_builtin\\_%")
}

predicate whitelistPow(FunctionCall fc) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ where
// unfortunately cannot use numeric value here because // O_CREAT is defined differently on different OSes:
// https://github.com/red/red/blob/92feb0c0d5f91e087ab35fface6906afbf99b603/runtime/definitions.reds#L477-L491
// this may introduce false negatives
fctmp.getArgument(1).(BitwiseOrExpr).getAChild*().getValueText().matches("O_CREAT") or
fctmp.getArgument(1).(BitwiseOrExpr).getAChild*().getValueText() = "O_CREAT" or
fctmp.getArgument(1).getValueText().matches("%O_CREAT%")
) and
fctmp.getNumberOfArguments() = 2 and
Expand Down
2 changes: 1 addition & 1 deletion cpp/ql/src/jsf/4.05 Libraries/AV Rule 23.ql
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import cpp

from Function f
where
f.getName().regexpMatch("atof|atoi|atol") and
f.getName() = ["atof", "atoi", "atol"] and
f.getFile().getAbsolutePath().matches("%stdlib.h")
select f.getACallToThisFunction(),
"AV Rule 23: The library functions atof, atoi and atol from library <stdlib.h> shall not be used."
2 changes: 1 addition & 1 deletion cpp/ql/src/jsf/4.05 Libraries/AV Rule 24.ql
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import cpp

from Function f
where
f.getName().regexpMatch("abort|exit|getenv|system") and
f.getName() = ["abort", "exit", "getenv", "system"] and
f.getFile().getAbsolutePath().matches("%stdlib.h")
select f.getACallToThisFunction(),
"The library functions abort, exit, getenv and system from library <stdlib.h> should not be used."
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class UnsafeYearCreationFromArithmeticConfiguration extends TaintTracking::Confi
override predicate isSource(DataFlow::Node source) {
exists(ArithmeticOperation ao, PropertyAccess pa | ao = source.asExpr() |
pa = ao.getAChild*() and
pa.getProperty().getQualifiedName().matches("System.DateTime.Year")
pa.getProperty().hasQualifiedName("System.DateTime.Year")
)
}

Expand Down
2 changes: 1 addition & 1 deletion java/ql/lib/semmle/code/java/Collections.qll
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ class CollectionMutation extends MethodAccess {
/** A method that queries the contents of a collection without mutating it. */
class CollectionQueryMethod extends CollectionMethod {
CollectionQueryMethod() {
pragma[only_bind_into](this).getName().regexpMatch("contains|containsAll|get|size|peek")
pragma[only_bind_into](this).getName() = ["contains", "containsAll", "get", "size", "peek"]
}
}

Expand Down
5 changes: 2 additions & 3 deletions java/ql/lib/semmle/code/java/Maps.qll
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,8 @@ class MapMutation extends MethodAccess {
/** A method that queries the contents of the map it belongs to without mutating it. */
class MapQueryMethod extends MapMethod {
MapQueryMethod() {
pragma[only_bind_into](this)
.getName()
.regexpMatch("get|containsKey|containsValue|entrySet|keySet|values|isEmpty|size")
pragma[only_bind_into](this).getName() =
["get", "containsKey", "containsValue", "entrySet", "keySet", "values", "isEmpty", "size"]
}
}

Expand Down
25 changes: 13 additions & 12 deletions java/ql/lib/semmle/code/java/Type.qll
Original file line number Diff line number Diff line change
Expand Up @@ -1002,7 +1002,9 @@ class FunctionalInterface extends Interface {
* and `double`.
*/
class PrimitiveType extends Type, @primitive {
PrimitiveType() { this.getName().regexpMatch("float|double|int|boolean|short|byte|char|long") }
PrimitiveType() {
this.getName() = ["float", "double", "int", "boolean", "short", "byte", "char", "long"]
}

/** Gets the boxed type corresponding to this primitive type. */
BoxedType getBoxedType() { result.getPrimitiveType() = this }
Expand Down Expand Up @@ -1217,9 +1219,9 @@ predicate erasedHaveIntersection(RefType t1, RefType t2) {
class IntegralType extends Type {
IntegralType() {
exists(string name |
name = this.(PrimitiveType).getName() or name = this.(BoxedType).getPrimitiveType().getName()
name = [this.(PrimitiveType).getName(), this.(BoxedType).getPrimitiveType().getName()]
|
name.regexpMatch("byte|char|short|int|long")
name = ["byte", "char", "short", "int", "long"]
)
}
}
Expand All @@ -1228,7 +1230,7 @@ class IntegralType extends Type {
class BooleanType extends Type {
BooleanType() {
exists(string name |
name = this.(PrimitiveType).getName() or name = this.(BoxedType).getPrimitiveType().getName()
name = [this.(PrimitiveType).getName(), this.(BoxedType).getPrimitiveType().getName()]
|
name = "boolean"
)
Expand All @@ -1239,7 +1241,7 @@ class BooleanType extends Type {
class CharacterType extends Type {
CharacterType() {
exists(string name |
name = this.(PrimitiveType).getName() or name = this.(BoxedType).getPrimitiveType().getName()
name = [this.(PrimitiveType).getName(), this.(BoxedType).getPrimitiveType().getName()]
|
name = "char"
)
Expand All @@ -1250,10 +1252,9 @@ class CharacterType extends Type {
class NumericType extends Type {
NumericType() {
exists(string name |
name = this.(PrimitiveType).getName() or
name = this.(BoxedType).getPrimitiveType().getName()
name = [this.(PrimitiveType).getName(), this.(BoxedType).getPrimitiveType().getName()]
|
name.regexpMatch("byte|short|int|long|double|float")
name = ["byte", "short", "int", "long", "double", "float"]
)
}
}
Expand All @@ -1262,9 +1263,9 @@ class NumericType extends Type {
class NumericOrCharType extends Type {
NumericOrCharType() {
exists(string name |
name = this.(PrimitiveType).getName() or name = this.(BoxedType).getPrimitiveType().getName()
name = [this.(PrimitiveType).getName(), this.(BoxedType).getPrimitiveType().getName()]
|
name.regexpMatch("byte|char|short|int|long|double|float")
name = ["byte", "char", "short", "int", "long", "double", "float"]
)
}
}
Expand All @@ -1273,9 +1274,9 @@ class NumericOrCharType extends Type {
class FloatingPointType extends Type {
FloatingPointType() {
exists(string name |
name = this.(PrimitiveType).getName() or name = this.(BoxedType).getPrimitiveType().getName()
name = [this.(PrimitiveType).getName(), this.(BoxedType).getPrimitiveType().getName()]
|
name.regexpMatch("float|double")
name = ["float", "double"]
)
}
}
10 changes: 5 additions & 5 deletions java/ql/lib/semmle/code/java/dataflow/RangeAnalysis.qll
Original file line number Diff line number Diff line change
Expand Up @@ -337,15 +337,15 @@ private predicate safeCast(Type fromtyp, Type totyp) {
exists(PrimitiveType pfrom, PrimitiveType pto | pfrom = fromtyp and pto = totyp |
pfrom = pto
or
pfrom.hasName("char") and pto.getName().regexpMatch("int|long|float|double")
pfrom.hasName("char") and pto.hasName(["int", "long", "float", "double"])
or
pfrom.hasName("byte") and pto.getName().regexpMatch("short|int|long|float|double")
pfrom.hasName("byte") and pto.hasName(["short", "int", "long", "float", "double"])
or
pfrom.hasName("short") and pto.getName().regexpMatch("int|long|float|double")
pfrom.hasName("short") and pto.hasName(["int", "long", "float", "double"])
or
pfrom.hasName("int") and pto.getName().regexpMatch("long|float|double")
pfrom.hasName("int") and pto.hasName(["long", "float", "double"])
or
pfrom.hasName("long") and pto.getName().regexpMatch("float|double")
pfrom.hasName("long") and pto.hasName(["float", "double"])
or
pfrom.hasName("float") and pto.hasName("double")
or
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ private predicate localAdditionalTaintUpdateStep(Expr src, Expr sink) {

private class BulkData extends RefType {
BulkData() {
this.(Array).getElementType().(PrimitiveType).getName().regexpMatch("byte|char")
this.(Array).getElementType().(PrimitiveType).hasName(["byte", "char"])
or
exists(RefType t | this.getASourceSupertype*() = t |
t.hasQualifiedName("java.io", "InputStream") or
Expand Down Expand Up @@ -321,15 +321,15 @@ private predicate argToMethodStep(Expr tracked, MethodAccess sink) {
exists(Method springResponseEntityOfOk |
sink.getMethod() = springResponseEntityOfOk and
springResponseEntityOfOk.getDeclaringType() instanceof SpringResponseEntity and
springResponseEntityOfOk.getName().regexpMatch("ok|of") and
springResponseEntityOfOk.hasName(["ok", "of"]) and
tracked = sink.getArgument(0) and
tracked.getType() instanceof TypeString
)
or
exists(Method springResponseEntityBody |
sink.getMethod() = springResponseEntityBody and
springResponseEntityBody.getDeclaringType() instanceof SpringResponseEntityBodyBuilder and
springResponseEntityBody.getName().regexpMatch("body") and
springResponseEntityBody.hasName("body") and
tracked = sink.getArgument(0) and
tracked.getType() instanceof TypeString
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class FitFixtureEntryPoint extends CallableEntryPoint {
* FitNesse entry points externally defined.
*/
class FitNesseSlimEntryPointData extends ExternalData {
FitNesseSlimEntryPointData() { getDataPath().matches("fitnesse.csv") }
FitNesseSlimEntryPointData() { getDataPath() = "fitnesse.csv" }

/**
* Gets the class name.
Expand Down
2 changes: 1 addition & 1 deletion java/ql/lib/semmle/code/java/frameworks/Mockito.qll
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class MockitoInitedTest extends Class {
*/
class MockitoAnnotation extends Annotation {
MockitoAnnotation() {
this.getType().getPackage().getName().matches("org.mockito") or
this.getType().getPackage().hasName("org.mockito") or
this.getType().getPackage().getName().matches("org.mockito.%")
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ private class SliceProviderLifecycleStep extends AdditionalValueStep {

private class SliceActionsInheritTaint extends DataFlow::SyntheticFieldContent,
TaintInheritingContent {
SliceActionsInheritTaint() { this.getField().matches("androidx.slice.Slice.action") }
SliceActionsInheritTaint() { this.getField() = "androidx.slice.Slice.action" }
}

private class SliceBuildersSummaryModels extends SummaryModelCsv {
Expand Down
6 changes: 3 additions & 3 deletions java/ql/lib/semmle/code/java/security/ExternalAPIs.qll
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ private class DefaultSafeExternalApiMethod extends SafeExternalApiMethod {
DefaultSafeExternalApiMethod() {
this instanceof EqualsMethod
or
this.getName().regexpMatch("size|length|compareTo|getClass|lastIndexOf")
this.hasName(["size", "length", "compareTo", "getClass", "lastIndexOf"])
or
this.getDeclaringType().hasQualifiedName("org.apache.commons.lang3", "Validate")
or
Expand All @@ -42,7 +42,7 @@ private class DefaultSafeExternalApiMethod extends SafeExternalApiMethod {
this.getName() = "isDigit"
or
this.getDeclaringType().hasQualifiedName("java.lang", "String") and
this.getName().regexpMatch("equalsIgnoreCase|regionMatches")
this.hasName(["equalsIgnoreCase", "regionMatches"])
or
this.getDeclaringType().hasQualifiedName("java.lang", "Boolean") and
this.getName() = "parseBoolean"
Expand All @@ -51,7 +51,7 @@ private class DefaultSafeExternalApiMethod extends SafeExternalApiMethod {
this.getName() = "closeQuietly"
or
this.getDeclaringType().hasQualifiedName("org.springframework.util", "StringUtils") and
this.getName().regexpMatch("hasText|isEmpty")
this.hasName(["hasText", "isEmpty"])
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ predicate looksLikeResolveClassStep(DataFlow::Node fromNode, DataFlow::Node toNo
m = ma.getMethod() and arg = ma.getArgument(i)
|
m.getReturnType() instanceof TypeClass and
m.getName().toLowerCase().regexpMatch("resolve|load|class|type") and
m.getName().toLowerCase() = ["resolve", "load", "class", "type"] and
arg.getType() instanceof TypeString and
arg = fromNode.asExpr() and
ma = toNode.asExpr()
Expand All @@ -52,7 +52,7 @@ predicate looksLikeInstantiateClassStep(DataFlow::Node fromNode, DataFlow::Node
m = ma.getMethod() and arg = ma.getArgument(i)
|
m.getReturnType() instanceof TypeObject and
m.getName().toLowerCase().regexpMatch("instantiate|instance|create|make|getbean") and
m.getName().toLowerCase() = ["instantiate", "instance", "create", "make", "getbean"] and
arg.getType() instanceof TypeClass and
arg = fromNode.asExpr() and
ma = toNode.asExpr()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,6 @@ predicate springUrlRedirectTaintStep(DataFlow::Node fromNode, DataFlow::Node toN
predicate nonLocationHeaderSanitizer(DataFlow::Node node) {
exists(HttpHeadersAddSetMethodAccess ma, Argument firstArg | node.asExpr() = ma.getArgument(1) |
firstArg = ma.getArgument(0) and
not firstArg.(CompileTimeConstantExpr).getStringValue().matches("Location")
not firstArg.(CompileTimeConstantExpr).getStringValue() = "Location"
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ string asPartialModel(TargetApiSpecific api) {
}

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

/**
Expand Down
4 changes: 1 addition & 3 deletions javascript/ql/lib/semmle/javascript/Expr.qll
Original file line number Diff line number Diff line change
Expand Up @@ -2286,9 +2286,7 @@ class ComprehensionExpr extends @comprehension_expr, Expr {

/** Holds if this is a legacy postfix comprehension expression. */
predicate isPostfix() {
exists(Token tk | tk = this.getFirstToken().getNextToken() |
not tk.getValue().regexpMatch("if|for")
)
exists(Token tk | tk = this.getFirstToken().getNextToken() | not tk.getValue() = ["if", "for"])
}

override string getAPrimaryQlClass() { result = "ComprehensionExpr" }
Expand Down
2 changes: 1 addition & 1 deletion javascript/ql/lib/semmle/javascript/frameworks/xUnit.qll
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ private predicate xUnitDetected() {
private predicate possiblyAttribute(Expr e, string name) {
exists(Identifier id | id = e or id = e.(CallExpr).getCallee() |
name = id.getName() and
name.regexpMatch("Async|Data|Fact|Fixture|Import|ImportJson|Skip|Trait")
name = ["Async", "Data", "Fact", "Fixture", "Import", "ImportJson", "Skip", "Trait"]
)
}

Expand Down
2 changes: 1 addition & 1 deletion javascript/ql/src/Declarations/DeadStoreOfGlobal.ql
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ where
// 'v' is not externally declared...
not exists(ExternalVarDecl d | d.getName() = v.getName() |
// ...as a member of {Window,Worker,WebWorker}.prototype
d.(ExternalInstanceMemberDecl).getBaseName().regexpMatch("Window|Worker|WebWorker")
d.(ExternalInstanceMemberDecl).getBaseName() = ["Window", "Worker", "WebWorker"]
or
// ...or as a member of window
d.(ExternalStaticMemberDecl).getBaseName() = "window"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import javascript
from PropAccess acc, ArgumentsVariable args
where
acc.getBase() = args.getAnAccess() and
acc.getPropertyName().regexpMatch("caller|callee") and
acc.getPropertyName() = ["caller", "callee"] and
// don't flag cases where the variable can never contain an arguments object
not exists(Function fn | args = fn.getVariable()) and
not exists(Parameter p | args = p.getAVariable()) and
Expand Down
7 changes: 5 additions & 2 deletions javascript/ql/src/LanguageFeatures/BadTypeof.ql
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,11 @@ from EqOrSwitch et, TypeofExpr typeof, ConstantString str
where
typeof = et.getAnOperand().getUnderlyingValue() and
str = et.getAnOperand().getUnderlyingValue() and
not str.getStringValue()
.regexpMatch("undefined|boolean|number|string|object|function|symbol|unknown|date|bigint")
not str.getStringValue() =
[
"undefined", "boolean", "number", "string", "object", "function", "symbol", "unknown", "date",
"bigint"
]
select typeof,
"The result of this 'typeof' expression is compared to '$@', but the two can never be equal.",
str, str.getStringValue()
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ private module Authlib {
override DataFlow::Node getAlgorithm() {
exists(KeyValuePair headerDict |
headerDict = this.getArg(0).asExpr().(Dict).getItem(_) and
headerDict.getKey().(Str_).getS().matches("alg") and
headerDict.getKey().(Str_).getS() = "alg" and
result.asExpr() = headerDict.getValue()
)
}
Expand Down
Loading