From d85d009a54b1f33b2ba6373a5080aa853feaf6c2 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 13 Oct 2021 13:19:06 +0100 Subject: [PATCH 1/4] Java: Replace '.prefix'/'.suffix' with '.matches'. --- .../semmle/code/java/frameworks/gigaspaces/GigaSpaces.qll | 6 +++--- .../semmle/code/java/frameworks/spring/SpringProfile.qll | 2 +- java/ql/lib/semmle/code/xml/MavenPom.qll | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/java/ql/lib/semmle/code/java/frameworks/gigaspaces/GigaSpaces.qll b/java/ql/lib/semmle/code/java/frameworks/gigaspaces/GigaSpaces.qll index 6b70770b70e..b7596ebab49 100644 --- a/java/ql/lib/semmle/code/java/frameworks/gigaspaces/GigaSpaces.qll +++ b/java/ql/lib/semmle/code/java/frameworks/gigaspaces/GigaSpaces.qll @@ -37,7 +37,7 @@ predicate isGigaSpacesEventMethod(Method eventMethod) { class GigaSpacesSpaceIdGetterMethod extends Method { GigaSpacesSpaceIdGetterMethod() { getAnAnnotation().getType().hasQualifiedName("com.gigaspaces.annotation.pojo", "SpaceId") and - getName().prefix(3) = "get" + getName().matches("get%") } } @@ -48,7 +48,7 @@ class GigaSpacesSpaceIdSetterMethod extends Method { GigaSpacesSpaceIdSetterMethod() { exists(GigaSpacesSpaceIdGetterMethod getterMethod | getterMethod.getDeclaringType() = getDeclaringType() and - getName().prefix(3) = "set" + getName().matches("set%") | getterMethod.getName().suffix(3) = getName().suffix(3) ) @@ -62,6 +62,6 @@ class GigaSpacesSpaceIdSetterMethod extends Method { class GigaSpacesSpaceRoutingMethod extends Method { GigaSpacesSpaceRoutingMethod() { getAnAnnotation().getType().hasQualifiedName("com.gigaspaces.annotation.pojo", "SpaceRouting") and - getName().prefix(3) = "get" + getName().matches("get%") } } diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringProfile.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringProfile.qll index 32ee55723b2..17fedacdefe 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringProfile.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringProfile.qll @@ -37,7 +37,7 @@ class SpringProfileExpr extends string { * A Spring profile expression that begins with "!", indicating a negated expression. */ class NotSpringProfileExpr extends SpringProfileExpr { - NotSpringProfileExpr() { this.prefix(1) = "!" } + NotSpringProfileExpr() { this.matches("!%") } /** * Gets the profile described in this profile expression. diff --git a/java/ql/lib/semmle/code/xml/MavenPom.qll b/java/ql/lib/semmle/code/xml/MavenPom.qll index fe6985ba811..921f9be0bff 100644 --- a/java/ql/lib/semmle/code/xml/MavenPom.qll +++ b/java/ql/lib/semmle/code/xml/MavenPom.qll @@ -129,7 +129,7 @@ class Pom extends ProtoPom { * occurs by considering the properties defined by this project or an ancestor project. */ string resolvePlaceholder(string name) { - if name.prefix(8) = "project." + if name.matches("project.%") then exists(PomElement p | p = getProjectProperty() and From f3bb0a676e06fa7be402f3354d75e7655a22bea0 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 13 Oct 2021 13:19:45 +0100 Subject: [PATCH 2/4] JS: Replace '.prefix'/'.suffix' with '.matches'. --- .../ql/lib/semmle/javascript/frameworks/NodeJSLib.qll | 2 +- .../javascript/frameworks/SystemCommandExecutors.qll | 4 +--- .../ql/lib/semmle/javascript/security/UselessUseOfCat.qll | 7 ++----- javascript/ql/src/Security/CWE-730/ServerCrash.ql | 2 +- 4 files changed, 5 insertions(+), 10 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll b/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll index 43fde9639c2..7a88b3f94c3 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll @@ -727,7 +727,7 @@ module NodeJSLib { result = getParameter(1).getARhs() } - override predicate isSync() { "Sync" = methodName.suffix(methodName.length() - 4) } + override predicate isSync() { methodName.matches("%Sync") } override DataFlow::Node getOptionsArg() { not result.getALocalSource() instanceof DataFlow::FunctionNode and // looks like callback diff --git a/javascript/ql/lib/semmle/javascript/frameworks/SystemCommandExecutors.qll b/javascript/ql/lib/semmle/javascript/frameworks/SystemCommandExecutors.qll index ce445cfd174..89eb8c9e9ea 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/SystemCommandExecutors.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/SystemCommandExecutors.qll @@ -107,9 +107,7 @@ private class SystemCommandExecutors extends SystemCommandExecution, DataFlow::I */ bindingset[name] private boolean getSync(string name) { - if name.suffix(name.length() - 4) = "Sync" or name.suffix(name.length() - 4) = "sync" - then result = true - else result = false + if name.matches("%Sync") or name.matches("%sync") then result = true else result = false } private class RemoteCommandExecutor extends SystemCommandExecution, DataFlow::InvokeNode { diff --git a/javascript/ql/lib/semmle/javascript/security/UselessUseOfCat.qll b/javascript/ql/lib/semmle/javascript/security/UselessUseOfCat.qll index 604a8182e96..eda163f053f 100644 --- a/javascript/ql/lib/semmle/javascript/security/UselessUseOfCat.qll +++ b/javascript/ql/lib/semmle/javascript/security/UselessUseOfCat.qll @@ -303,14 +303,11 @@ module PrettyPrintCatCall { bindingset[str] private string createSimplifiedStringConcat(string str) { // Remove an initial ""+ (e.g. in `""+file`) - if str.prefix(5) = "\"\" + " + if str.matches("\"\" + %") then result = str.suffix(5) else // prettify `${newpath}` to just newpath - if - str.prefix(3) = "`${" and - str.suffix(str.length() - 2) = "}`" and - not str.suffix(3).matches("%{%") + if str.matches("`${%") and str.matches("}`%") and not str.suffix(3).matches("%{%") then result = str.prefix(str.length() - 2).suffix(3) else result = str } diff --git a/javascript/ql/src/Security/CWE-730/ServerCrash.ql b/javascript/ql/src/Security/CWE-730/ServerCrash.ql index 7c16287d48c..336cc2abf70 100644 --- a/javascript/ql/src/Security/CWE-730/ServerCrash.ql +++ b/javascript/ql/src/Security/CWE-730/ServerCrash.ql @@ -104,7 +104,7 @@ class AsyncSentinelCall extends DataFlow::CallNode { exists(DataFlow::FunctionNode node | node.getAstNode() = asyncCallee | // manual models exists(string memberName | - not "Sync" = memberName.suffix(memberName.length() - 4) and + not memberName.matches("%Sync") and this = NodeJSLib::FS::moduleMember(memberName).getACall() and node = this.getCallback([1 .. 2]) ) From a80860cdc6b06b363b0d0919600ab383a470b449 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 13 Oct 2021 13:19:58 +0100 Subject: [PATCH 3/4] Python: Replace '.prefix'/'.suffix' with '.matches'. --- python/ql/lib/semmle/python/templates/PyxlTags.qll | 2 +- python/ql/lib/semmle/python/web/Http.qll | 2 +- python/ql/src/Security/CWE-798/HardcodedCredentials.ql | 2 +- python/ql/src/analysis/Consistency.ql | 2 +- python/ql/test/library-tests/PointsTo/customise/test.ql | 4 ++-- python/ql/test/library-tests/PointsTo/new/Consistency.ql | 2 +- .../ql/test/library-tests/taint/extensions/ExtensionsLib.qll | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/python/ql/lib/semmle/python/templates/PyxlTags.qll b/python/ql/lib/semmle/python/templates/PyxlTags.qll index f0e663cdad0..abfef070d78 100644 --- a/python/ql/lib/semmle/python/templates/PyxlTags.qll +++ b/python/ql/lib/semmle/python/templates/PyxlTags.qll @@ -29,7 +29,7 @@ private predicate pyxl_tag(Call c, string name) { } class PyxlHtmlTag extends PyxlTag { - PyxlHtmlTag() { this.getPyxlTagName().prefix(2) = "x_" } + PyxlHtmlTag() { this.getPyxlTagName().matches("x\\_%") } string getTagName() { result = this.getPyxlTagName().suffix(2) } diff --git a/python/ql/lib/semmle/python/web/Http.qll b/python/ql/lib/semmle/python/web/Http.qll index 527a050d814..fc1b1bc5756 100644 --- a/python/ql/lib/semmle/python/web/Http.qll +++ b/python/ql/lib/semmle/python/web/Http.qll @@ -33,7 +33,7 @@ class WsgiEnvironment extends TaintKind { ( text = "QUERY_STRING" or text = "PATH_INFO" or - text.prefix(5) = "HTTP_" + text.matches("HTTP\\_%") ) ) } diff --git a/python/ql/src/Security/CWE-798/HardcodedCredentials.ql b/python/ql/src/Security/CWE-798/HardcodedCredentials.ql index cd00908fe05..895352be75c 100644 --- a/python/ql/src/Security/CWE-798/HardcodedCredentials.ql +++ b/python/ql/src/Security/CWE-798/HardcodedCredentials.ql @@ -88,7 +88,7 @@ class CredentialSink extends TaintSink { CredentialSink() { exists(string name | name.regexpMatch(getACredentialRegex()) and - not name.suffix(name.length() - 4) = "file" + not name.matches("%file") | any(FunctionValue func).getNamedArgumentForCall(_, name) = this or diff --git a/python/ql/src/analysis/Consistency.ql b/python/ql/src/analysis/Consistency.ql index a504216a252..698a3d95b3a 100644 --- a/python/ql/src/analysis/Consistency.ql +++ b/python/ql/src/analysis/Consistency.ql @@ -141,7 +141,7 @@ predicate builtin_object_consistency(string clsname, string problem, string what or not exists(o.toString()) and problem = "no toString" and - not exists(string name | name.prefix(7) = "_semmle" | py_special_objects(o, name)) and + not exists(string name | name.matches("\\_semmle%") | py_special_objects(o, name)) and not o = unknownValue() ) } diff --git a/python/ql/test/library-tests/PointsTo/customise/test.ql b/python/ql/test/library-tests/PointsTo/customise/test.ql index c2fceb95225..f101e4f2a5d 100644 --- a/python/ql/test/library-tests/PointsTo/customise/test.ql +++ b/python/ql/test/library-tests/PointsTo/customise/test.ql @@ -11,7 +11,7 @@ class HasTypeFact extends CustomPointsToOriginFact { exists(FunctionObject func, string name | func.getACall() = this and name = func.getName() and - name.prefix("has_type_".length()) = "has_type_" + name.matches("has\\_type\\_%") ) } @@ -19,7 +19,7 @@ class HasTypeFact extends CustomPointsToOriginFact { exists(FunctionObject func, string name | func.getACall() = this and name = func.getName() and - name.prefix("has_type_".length()) = "has_type_" + name.matches("has\\_type\\_%") | cls.getName() = name.suffix("has_type_".length()) ) and diff --git a/python/ql/test/library-tests/PointsTo/new/Consistency.ql b/python/ql/test/library-tests/PointsTo/new/Consistency.ql index 282b96fc541..0ee1a392ef2 100644 --- a/python/ql/test/library-tests/PointsTo/new/Consistency.ql +++ b/python/ql/test/library-tests/PointsTo/new/Consistency.ql @@ -104,7 +104,7 @@ predicate ssa_consistency(string clsname, string problem, string what) { or exists(EssaDefinition def | clsname = def.getAQlClass() and - clsname.prefix(4) = "Essa" and + clsname.matches("Essa%") and what = " at " + def.getLocation() and problem = "not covered by Python-specific subclass." ) diff --git a/python/ql/test/library-tests/taint/extensions/ExtensionsLib.qll b/python/ql/test/library-tests/taint/extensions/ExtensionsLib.qll index 08ba0ce6e40..4ae53e94a38 100644 --- a/python/ql/test/library-tests/taint/extensions/ExtensionsLib.qll +++ b/python/ql/test/library-tests/taint/extensions/ExtensionsLib.qll @@ -28,7 +28,7 @@ class SimpleSource extends TaintSource { predicate visit_call(CallNode call, FunctionObject func) { exists(AttrNode attr, ClassObject cls, string name | - name.prefix(6) = "visit_" and + name.matches("visit\\_%") and func = cls.lookupAttribute(name) and attr.getObject("visit").refersTo(_, cls, _) and attr = call.getFunction() From 4991301f365063f16222a5ee45521b5a3eec1dc1 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 13 Oct 2021 19:45:02 +0100 Subject: [PATCH 4/4] JS: Fix incorrect fix. --- .../ql/lib/semmle/javascript/security/UselessUseOfCat.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/security/UselessUseOfCat.qll b/javascript/ql/lib/semmle/javascript/security/UselessUseOfCat.qll index eda163f053f..b2b65038508 100644 --- a/javascript/ql/lib/semmle/javascript/security/UselessUseOfCat.qll +++ b/javascript/ql/lib/semmle/javascript/security/UselessUseOfCat.qll @@ -307,7 +307,7 @@ module PrettyPrintCatCall { then result = str.suffix(5) else // prettify `${newpath}` to just newpath - if str.matches("`${%") and str.matches("}`%") and not str.suffix(3).matches("%{%") + if str.matches("`${%") and str.matches("%}`") and not str.suffix(3).matches("%{%") then result = str.prefix(str.length() - 2).suffix(3) else result = str }