diff --git a/cpp/ql/lib/semmle/code/cpp/commons/Printf.qll b/cpp/ql/lib/semmle/code/cpp/commons/Printf.qll index 703c4dd2879e..71a31d03aac1 100644 --- a/cpp/ql/lib/semmle/code/cpp/commons/Printf.qll +++ b/cpp/ql/lib/semmle/code/cpp/commons/Printf.qll @@ -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() @@ -912,7 +912,7 @@ 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() ) @@ -920,7 +920,7 @@ class FormatLiteral extends Literal { 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) ) } diff --git a/cpp/ql/src/Likely Bugs/Conversion/LossyFunctionResultCast.ql b/cpp/ql/src/Likely Bugs/Conversion/LossyFunctionResultCast.ql index 2a8aba6a9610..dee723e26867 100644 --- a/cpp/ql/src/Likely Bugs/Conversion/LossyFunctionResultCast.ql +++ b/cpp/ql/src/Likely Bugs/Conversion/LossyFunctionResultCast.ql @@ -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) { diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-266/IncorrectPrivilegeAssignment.ql b/cpp/ql/src/experimental/Security/CWE/CWE-266/IncorrectPrivilegeAssignment.ql index 8411d0ba2e21..5bdd5a21fe52 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-266/IncorrectPrivilegeAssignment.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-266/IncorrectPrivilegeAssignment.ql @@ -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 diff --git a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 23.ql b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 23.ql index 9bb63cb6b29b..ff4b1baec76e 100644 --- a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 23.ql +++ b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 23.ql @@ -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 shall not be used." diff --git a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 24.ql b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 24.ql index 9e0fd1d5de8f..3bf27d8121c2 100644 --- a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 24.ql +++ b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 24.ql @@ -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 should not be used." diff --git a/csharp/ql/src/Likely Bugs/LeapYear/UnsafeYearConstruction.ql b/csharp/ql/src/Likely Bugs/LeapYear/UnsafeYearConstruction.ql index fe0c5707742f..838406ab82e9 100644 --- a/csharp/ql/src/Likely Bugs/LeapYear/UnsafeYearConstruction.ql +++ b/csharp/ql/src/Likely Bugs/LeapYear/UnsafeYearConstruction.ql @@ -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") ) } diff --git a/java/ql/lib/semmle/code/java/Collections.qll b/java/ql/lib/semmle/code/java/Collections.qll index 7e39aa6d704e..05e8ffbe7e4a 100644 --- a/java/ql/lib/semmle/code/java/Collections.qll +++ b/java/ql/lib/semmle/code/java/Collections.qll @@ -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"] } } diff --git a/java/ql/lib/semmle/code/java/Maps.qll b/java/ql/lib/semmle/code/java/Maps.qll index 6b9374bfc141..1157cb76f5c5 100644 --- a/java/ql/lib/semmle/code/java/Maps.qll +++ b/java/ql/lib/semmle/code/java/Maps.qll @@ -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"] } } diff --git a/java/ql/lib/semmle/code/java/Type.qll b/java/ql/lib/semmle/code/java/Type.qll index a421bbc3eb7e..a37f9810c442 100755 --- a/java/ql/lib/semmle/code/java/Type.qll +++ b/java/ql/lib/semmle/code/java/Type.qll @@ -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 } @@ -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"] ) } } @@ -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" ) @@ -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" ) @@ -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"] ) } } @@ -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"] ) } } @@ -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"] ) } } diff --git a/java/ql/lib/semmle/code/java/dataflow/RangeAnalysis.qll b/java/ql/lib/semmle/code/java/dataflow/RangeAnalysis.qll index 1046bcc3b83f..a72b3c67b06d 100644 --- a/java/ql/lib/semmle/code/java/dataflow/RangeAnalysis.qll +++ b/java/ql/lib/semmle/code/java/dataflow/RangeAnalysis.qll @@ -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 diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll b/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll index 6b921a93e6ff..cdb54eca4358 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll @@ -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 @@ -321,7 +321,7 @@ 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 ) @@ -329,7 +329,7 @@ private predicate argToMethodStep(Expr tracked, MethodAccess sink) { 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 ) diff --git a/java/ql/lib/semmle/code/java/deadcode/frameworks/FitNesseEntryPoints.qll b/java/ql/lib/semmle/code/java/deadcode/frameworks/FitNesseEntryPoints.qll index af050ab0da17..85acb57c539a 100644 --- a/java/ql/lib/semmle/code/java/deadcode/frameworks/FitNesseEntryPoints.qll +++ b/java/ql/lib/semmle/code/java/deadcode/frameworks/FitNesseEntryPoints.qll @@ -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. diff --git a/java/ql/lib/semmle/code/java/frameworks/Mockito.qll b/java/ql/lib/semmle/code/java/frameworks/Mockito.qll index a87050966b29..af1617600636 100644 --- a/java/ql/lib/semmle/code/java/frameworks/Mockito.qll +++ b/java/ql/lib/semmle/code/java/frameworks/Mockito.qll @@ -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.%") } } diff --git a/java/ql/lib/semmle/code/java/frameworks/android/Slice.qll b/java/ql/lib/semmle/code/java/frameworks/android/Slice.qll index e5e782e47e61..ad4f24adcd63 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/Slice.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/Slice.qll @@ -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 { diff --git a/java/ql/lib/semmle/code/java/security/ExternalAPIs.qll b/java/ql/lib/semmle/code/java/security/ExternalAPIs.qll index b4b8ea7fdd94..1356c152d237 100644 --- a/java/ql/lib/semmle/code/java/security/ExternalAPIs.qll +++ b/java/ql/lib/semmle/code/java/security/ExternalAPIs.qll @@ -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 @@ -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" @@ -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"]) } } diff --git a/java/ql/src/experimental/Security/CWE/CWE-470/UnsafeReflectionLib.qll b/java/ql/src/experimental/Security/CWE/CWE-470/UnsafeReflectionLib.qll index 803fe6107a12..a111c918555a 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-470/UnsafeReflectionLib.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-470/UnsafeReflectionLib.qll @@ -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() @@ -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() diff --git a/java/ql/src/experimental/Security/CWE/CWE-601/SpringUrlRedirect.qll b/java/ql/src/experimental/Security/CWE/CWE-601/SpringUrlRedirect.qll index 3791573eb9d1..1aded71c6617 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-601/SpringUrlRedirect.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-601/SpringUrlRedirect.qll @@ -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" ) } diff --git a/java/ql/src/utils/model-generator/internal/CaptureModelsSpecific.qll b/java/ql/src/utils/model-generator/internal/CaptureModelsSpecific.qll index dd7f62fe1330..c8de5b8f7c12 100644 --- a/java/ql/src/utils/model-generator/internal/CaptureModelsSpecific.qll +++ b/java/ql/src/utils/model-generator/internal/CaptureModelsSpecific.qll @@ -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"]) } /** diff --git a/javascript/ql/lib/semmle/javascript/Expr.qll b/javascript/ql/lib/semmle/javascript/Expr.qll index 9295fbb37579..7db74458bdf6 100644 --- a/javascript/ql/lib/semmle/javascript/Expr.qll +++ b/javascript/ql/lib/semmle/javascript/Expr.qll @@ -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" } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/xUnit.qll b/javascript/ql/lib/semmle/javascript/frameworks/xUnit.qll index e07bd29b3c32..0b2379dd6b13 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/xUnit.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/xUnit.qll @@ -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"] ) } diff --git a/javascript/ql/src/Declarations/DeadStoreOfGlobal.ql b/javascript/ql/src/Declarations/DeadStoreOfGlobal.ql index fc10f66f5333..e7d916c48f36 100644 --- a/javascript/ql/src/Declarations/DeadStoreOfGlobal.ql +++ b/javascript/ql/src/Declarations/DeadStoreOfGlobal.ql @@ -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" diff --git a/javascript/ql/src/LanguageFeatures/ArgumentsCallerCallee.ql b/javascript/ql/src/LanguageFeatures/ArgumentsCallerCallee.ql index fb7055d8f991..6354383f6c78 100644 --- a/javascript/ql/src/LanguageFeatures/ArgumentsCallerCallee.ql +++ b/javascript/ql/src/LanguageFeatures/ArgumentsCallerCallee.ql @@ -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 diff --git a/javascript/ql/src/LanguageFeatures/BadTypeof.ql b/javascript/ql/src/LanguageFeatures/BadTypeof.ql index 1da17f3a8e87..1b9213edd1aa 100644 --- a/javascript/ql/src/LanguageFeatures/BadTypeof.ql +++ b/javascript/ql/src/LanguageFeatures/BadTypeof.ql @@ -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() diff --git a/python/ql/src/experimental/semmle/python/libraries/Authlib.qll b/python/ql/src/experimental/semmle/python/libraries/Authlib.qll index f8121630e397..afb80950ea6e 100644 --- a/python/ql/src/experimental/semmle/python/libraries/Authlib.qll +++ b/python/ql/src/experimental/semmle/python/libraries/Authlib.qll @@ -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() ) } diff --git a/python/ql/src/external/Thrift.qll b/python/ql/src/external/Thrift.qll index cbaf562cbc4d..330aab7ee3f0 100644 --- a/python/ql/src/external/Thrift.qll +++ b/python/ql/src/external/Thrift.qll @@ -104,28 +104,28 @@ class ThriftType extends ThriftNamedElement { /** A thrift typedef */ class ThriftTypeDef extends ThriftNamedElement { - ThriftTypeDef() { kind.matches("typedef") } + ThriftTypeDef() { kind = "typedef" } override ThriftElement getNameElement() { result = this.getChild(2).getChild(0) } } /** A thrift enum declaration */ class ThriftEnum extends ThriftNamedElement { - ThriftEnum() { kind.matches("enum") } + ThriftEnum() { kind = "enum" } override ThriftElement getNameElement() { result = this.getChild(0).getChild(0) } } /** A thrift enum field */ class ThriftEnumField extends ThriftNamedElement { - ThriftEnumField() { kind.matches("enumfield") } + ThriftEnumField() { kind = "enumfield" } override ThriftElement getNameElement() { result = this.getChild(0).getChild(0) } } /** A thrift service declaration */ class ThriftService extends ThriftNamedElement { - ThriftService() { kind.matches("service") } + ThriftService() { kind = "service" } override ThriftElement getNameElement() { result = this.getChild(0).getChild(0) } @@ -139,7 +139,7 @@ class ThriftService extends ThriftNamedElement { /** A thrift function declaration */ class ThriftFunction extends ThriftNamedElement { - ThriftFunction() { kind.matches("function") } + ThriftFunction() { kind = "function" } override ThriftElement getNameElement() { result = this.getChild(2).getChild(0) } @@ -166,7 +166,7 @@ class ThriftFunction extends ThriftNamedElement { } class ThriftField extends ThriftNamedElement { - ThriftField() { kind.matches("field") } + ThriftField() { kind = "field" } override ThriftElement getNameElement() { result = this.getChild(4) } @@ -174,7 +174,7 @@ class ThriftField extends ThriftNamedElement { } class ThriftStruct extends ThriftNamedElement { - ThriftStruct() { kind.matches("struct") } + ThriftStruct() { kind = "struct" } override ThriftElement getNameElement() { result = this.getChild(0).getChild(0) } @@ -184,7 +184,7 @@ class ThriftStruct extends ThriftNamedElement { } class ThriftException extends ThriftNamedElement { - ThriftException() { kind.matches("exception") } + ThriftException() { kind = "exception" } override ThriftElement getNameElement() { result = this.getChild(0).getChild(0) } @@ -194,7 +194,7 @@ class ThriftException extends ThriftNamedElement { } class ThriftThrows extends ThriftElement { - ThriftThrows() { kind.matches("throws") } + ThriftThrows() { kind = "throws" } ThriftField getAThrows() { result = this.getChild(_) } } diff --git a/ql/ql/src/queries/style/UseStringComp.ql b/ql/ql/src/queries/style/UseStringComp.ql new file mode 100644 index 000000000000..7de268a70730 --- /dev/null +++ b/ql/ql/src/queries/style/UseStringComp.ql @@ -0,0 +1,31 @@ +/** + * @name Use of regexp to match a set of constant string + * @description Comparing against constant strings instead of a regexp can improve performance + * @kind problem + * @problem.severity recommendation + * @id ql/use-string-compare + * @tags maintainability + * @precision high + */ + +import ql +import codeql_ql.ast.internal.Type + +predicate problem(MemberCall call) { + call.getBase().getType().getASuperType*().(PrimitiveType).getName() = "string" and + ( + call.getMemberName() = "regexpMatch" and + call.getNumberOfArguments() = 1 and + call.getArgument(0).(String).getValue().regexpMatch("([a-zA-Z0-9]+\\|)*[a-zA-Z0-9]+") + or + exists(string reg | call.getMemberName() = "matches" | + call.getNumberOfArguments() = 1 and + reg = call.getArgument(0).(String).getValue() and + not reg.regexpMatch(".*(%|_).*") + ) + ) +} + +from AstNode node +where problem(node) +select node, "Use string comparison instead of regexp to compare against a constant set of string." diff --git a/ruby/ql/lib/codeql/ruby/security/internal/CleartextSources.qll b/ruby/ql/lib/codeql/ruby/security/internal/CleartextSources.qll index 8a3c59d795c6..672340fb5355 100644 --- a/ruby/ql/lib/codeql/ruby/security/internal/CleartextSources.qll +++ b/ruby/ql/lib/codeql/ruby/security/internal/CleartextSources.qll @@ -36,7 +36,7 @@ module CleartextSources { * sensitive data with a call to `sub`. */ private predicate effectiveSubRegExp(CfgNodes::ExprNodes::RegExpLiteralCfgNode re) { - re.getConstantValue().getStringlikeValue().matches([".*", ".+"]) + re.getConstantValue().getStringlikeValue() = [".*", ".+"] } /** @@ -44,7 +44,7 @@ module CleartextSources { * sensitive data with a call to `gsub`. */ private predicate effectiveGsubRegExp(CfgNodes::ExprNodes::RegExpLiteralCfgNode re) { - re.getConstantValue().getStringlikeValue().matches(".") + re.getConstantValue().getStringlikeValue() = "." } /**